<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Luca Bolognese's WebLog : Financial</title><link>http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx</link><description>Tags: Financial</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Financial Functions for .NET released !</title><link>http://blogs.msdn.com/lucabol/archive/2008/12/04/financial-functions-for-net-released.aspx</link><pubDate>Fri, 05 Dec 2008 00:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9177026</guid><dc:creator>lucabol</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9177026.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9177026</wfw:commentRss><description>&lt;P&gt;Today I released the following library on CodeGallery. It is the result of three months of coding during my paternity leave in Italy. You can get it from &lt;A href="http://code.msdn.microsoft.com/FinancialFunctions" mce_href="http://code.msdn.microsoft.com/FinancialFunctions"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;What is it?&lt;/B&gt; &lt;BR&gt;This is a .NET library that provides the full set of financial functions from Excel. The main goal for the library is compatibility with Excel, by providing the same functions, with the same behaviour. Note though that this is not a wrapper over the Excel library; the functions have been re-implemented in managed code so that you do not need to have Excel installed to use this library.&amp;nbsp;&lt;BR&gt;&lt;B&gt;&amp;nbsp;&lt;BR&gt;&lt;/B&gt;&lt;B&gt;Where I can find documentation on these functions?&lt;/B&gt; &lt;BR&gt;Just open Excel and click on Formulas/Financial or go to &lt;A href="http://office.microsoft.com/client/helppreview.aspx?AssetID=HP100791841033&amp;amp;ns=EXCEL&amp;amp;lcid=1033&amp;amp;CTT=3&amp;amp;Origin=HP100623561033" mce_href="http://office.microsoft.com/client/helppreview.aspx?AssetID=HP100791841033&amp;amp;ns=EXCEL&amp;amp;lcid=1033&amp;amp;CTT=3&amp;amp;Origin=HP100623561033"&gt;this&lt;/A&gt; &lt;BR&gt;&lt;B&gt;&lt;BR&gt;I don't think one of the function is right. Excel produces the wrong results! Why don't you do it right?&lt;/B&gt; &lt;BR&gt;My goal is to replicate Excel results (right and wrong). Feel free to contribute to the effort by coding what you think is the right solution and I'll add an ExcelCompliant flag to the function to conditionally invoke your code. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I use the library?&lt;/B&gt; &lt;BR&gt;Just add Financial.dll to the references in your project. The functions are provided as static methods on a Financial class in the System.Numeric namespace &lt;BR&gt;&lt;B&gt;I see the library was implemented with F#. But I don’t want to redistribute F# along with my application. What should I do?&lt;/B&gt; &lt;BR&gt;There are two versions of the library. One of them statically links the F# libraries so that there is no dependency on F#. However, this assembly larger, so if you have F# installed, you can use the FinancialNotStandalone.dll instead. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I run the tests?&lt;/B&gt; &lt;BR&gt;Run FinancialTests.exe. You need Excel 12 for the tests to work because they use Excel to test that the results are correct. You don't need Excel 12 to use the library in your own application. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I compile the library?&lt;/B&gt; &lt;BR&gt;You need to have F# September CTP installed (you can get it from &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c"&gt;here&lt;/A&gt;). There are two batch files (CreateLibraryStandalone.bat and CreateLibraryNotStandalon.bat). Run them to compile the dll. You might have to change the path to the F# compiler inside these files &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I compile the tests?&lt;/B&gt; &lt;BR&gt;Run CreateTests.bat &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Have you tested this thing?&lt;/B&gt; &lt;BR&gt;Yes, I do have 201,349 testcases running against it. You can easily raise that number significantly by adding new values to test in testdef.fs. If you have a multiproc machine the testcases will run faster as I parallelize their execution. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Have you run performance tests on it?&lt;/B&gt; &lt;BR&gt;Not at all. The only thing I checked is that all the recursive functions are tail recursive. Feel free to let me know if they are slow. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Are there any functions that behave different from Excel?&lt;/B&gt; &lt;BR&gt;Yes, there are two of them. &lt;BR&gt;&lt;I&gt;CoupDays&lt;/I&gt; &lt;BR&gt;The Excel algorithm seems wrong in that it doesn't respect the following: &lt;BR&gt;coupDays = coupDaysBS + coupDaysNC. &lt;BR&gt;This equality should stand. By manually counting the days, I'm pretty confident that my algorithm is correct.My result differs from Excel by +/- one or two days when the date spans a leap year. &lt;BR&gt;&lt;I&gt;VDB&lt;/I&gt; &lt;BR&gt;In the excel version of this algorithm the depreciation in the period (0,1) is not the same as the sum of the depreciations in periods (0,0.5) (0.5,1). &lt;BR&gt;VDB(100,10,13,0,0.5,1,0) + VDB(100,10,13,0.5,1,1,0) &amp;lt;&amp;gt; VDB(100,10,13,0,1,1,0) &lt;BR&gt;Notice that in Excel by using '1' (no_switch) instead of '0' as the last parameter everything works as expected. The last parameter should have no influence in the calculation given that in the first period there is no switch to sln depreciation. &lt;BR&gt;Overall, I think my algorithm is correct, even if it disagrees with Excel when startperiod is fractional. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Can you list the functions with their testcases results?&lt;/B&gt; &lt;BR&gt;Succeeded 1840/1840 for PV &lt;BR&gt;Succeeded 2024/2024 for FV &lt;BR&gt;Succeeded 2240/2240 for PMT &lt;BR&gt;Succeeded 853/853 for NPER &lt;BR&gt;Succeeded 5355/5355 for IPMT &lt;BR&gt;Succeeded 5355/5355 for PPMT &lt;BR&gt;Succeeded 208/208 for CUMIPMT &lt;BR&gt;Succeeded 208/208 for CUMPRINC &lt;BR&gt;Succeeded 624/624 for ISPMT &lt;BR&gt;Succeeded 12/12 for FVSCHEDULE &lt;BR&gt;Succeeded 9/9 for IRR &lt;BR&gt;Succeeded 21/21 for NPV &lt;BR&gt;Succeeded 147/147 for MIRR &lt;BR&gt;Succeeded 18/18 for XIRR &lt;BR&gt;Succeeded 396/396 for DB &lt;BR&gt;Succeeded 24/24 for SLN &lt;BR&gt;Succeeded 132/132 for SYD &lt;BR&gt;Succeeded 456/456 for DDB &lt;BR&gt;Succeeded 2544/2544 for VDB excluding fractional startdates &lt;BR&gt;Succeeded 11520/11520 for AMORLINC &lt;BR&gt;Succeeded 23040/23040 for AMORDEGRC &lt;BR&gt;Succeeded 15/15 for COUPDAYS excluding leap years &lt;BR&gt;Succeeded 915/915 for COUPDAYSBS &lt;BR&gt;Succeeded 915/915 for COUPDAYSNC &lt;BR&gt;Succeeded 915/915 for COUPNUM &lt;BR&gt;Succeeded 915/915 for COUPPCD &lt;BR&gt;Succeeded 915/915 for COUPNCD &lt;BR&gt;Succeeded 360/360 for ACCRINTM &lt;BR&gt;Succeeded 1920/1920 for ACCRINT &lt;BR&gt;Succeeded 10980/10980 for PRICE &lt;BR&gt;Succeeded 1940/1940 for PRICEMAT &lt;BR&gt;Succeeded 2910/2910 for YIELDMAT &lt;BR&gt;Succeeded 1395/1395 for YEARFRAC &lt;BR&gt;Succeeded 2745/2745 for INTRATE &lt;BR&gt;Succeeded 1290/1290 for RECEIVED &lt;BR&gt;Succeeded 2745/2745 for DISC &lt;BR&gt;Succeeded 3660/3660 for PRICEDISC &lt;BR&gt;Succeeded 2745/2745 for YIELDDISC &lt;BR&gt;Succeeded 48/48 for TBILLEQ &lt;BR&gt;Succeeded 69/69 for TBILLYIELD &lt;BR&gt;Succeeded 81/81 for TBILLPrice &lt;BR&gt;Succeeded 12/12 for DOLLARDE &lt;BR&gt;Succeeded 12/12 for DOLLARFR &lt;BR&gt;Succeeded 12/12 for EFFECT &lt;BR&gt;Succeeded 12/12 for NOMINAL &lt;BR&gt;Succeeded 5490/5490 for DURATION &lt;BR&gt;Succeeded 5490/5490 for MDURATION &lt;BR&gt;Succeeded 19320/19320 for ODDFPRICE &lt;BR&gt;Succeeded 30600/30600 for ODDLPRICE &lt;BR&gt;Succeeded 45900/45900 for ODDLYIELD &lt;BR&gt;Test Cases Succeeded 201349/201349&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9177026" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Downloading stock prices in F# - Part VI - Code posted</title><link>http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx</link><pubDate>Tue, 21 Oct 2008 01:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9008275</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9008275.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9008275</wfw:commentRss><description>&lt;P&gt;Other parts:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I - Data modeling&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II - Html scraping&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;Part III - Async loader for prices and divs&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx"&gt;Part IV - Async loader for splits&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V - Adjusting historical data&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/lukeh/default.aspx" mce_href="http://blogs.msdn.com/lukeh/default.aspx"&gt;An unnamed friend&lt;/A&gt; told me that I should stop posting small snippets of code and instead post entire solutions on &lt;A href="http://code.msdn.microsoft.com/" mce_href="http://code.msdn.microsoft.com/"&gt;CodeGallery&lt;/A&gt;. I did it for this one and &lt;A href="http://code.msdn.microsoft.com/DownloadStockPrices" mce_href="http://code.msdn.microsoft.com/DownloadStockPrices"&gt;here&lt;/A&gt; is the link.&lt;/P&gt;
&lt;P&gt;Here is what's in the zip file:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;BackTestF&lt;/STRONG&gt; - main library to download stock prices&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;Common.fs - common things used in the rest of the project (i.e. data modeling and common funcs)&lt;/LI&gt;
&lt;LI&gt;html.fs - functions to scrap html tables, rows and cells&lt;/LI&gt;
&lt;LI&gt;loader.fs - this is where the main async downloading algorithms are implemented&lt;/LI&gt;
&lt;LI&gt;persistence.fs - async saving and loading of stock prices to files&lt;/LI&gt;
&lt;LI&gt;algorithms.fs - async calculations of compound yearly returns given tickers and dates&lt;/LI&gt;
&lt;LI&gt;dotNetWrapper.fs - gives a .NET friendly interface to the whole library so that you can use it from C#/VB.NET&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Tests&lt;/STRONG&gt; - too few testcases running on xUnit (you need to download xUnit separately to run them&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;ReturnCalculator&lt;/STRONG&gt; - simple console application to show usage of the library&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Bob&lt;/STRONG&gt; - rough winforms UI application that uses the library. An unnamed friend (&lt;A href="http://msdn.microsoft.com/en-us/vbasic/bb735849.aspx" mce_href="http://msdn.microsoft.com/en-us/vbasic/bb735849.aspx"&gt;Jonathan&lt;/A&gt;) promised me that he was going to create a UI for my little library. My requirements were very simple: "I want the best UI app of this century, one that fully takes advantage of the async nature of my code". Bob doesn't fully satisfy my requirements yet :)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The code in persistence.fs, algorithms.fs and especially dotnetwrapper.fs is pretty rough and uninteresting. This is why I don't blog about it. I reserve the right to do it if I get around to clean it up.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9008275" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Downloading stock prices in F# - Part IV - Async loader for splits</title><link>http://blogs.msdn.com/lucabol/archive/2008/09/19/downloading-stock-prices-in-f-part-iv-async-loader-for-splits.aspx</link><pubDate>Sat, 20 Sep 2008 00:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8959474</guid><dc:creator>lucabol</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8959474.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8959474</wfw:commentRss><description>&lt;P&gt;Other parts:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/08/29/downloading-stock-prices-in-f-part-i-data-modeling.aspx"&gt;Part I - Data modeling&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/05/downloading-stock-prices-in-f-part-ii-html-scraping.aspx"&gt;Part II - Html scraping&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/12/downloading-stock-prices-in-f-part-iii-async-loader-for-prices-and-divs.aspx"&gt;Part III - Async loader for prices and divs&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/09/26/downloading-stock-prices-in-f-part-v-adjusting-historical-data.aspx"&gt;Part V - Adjusting historical data&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/10/20/downloading-stock-prices-in-f-part-vi-code-posted.aspx"&gt;Part VI - Code posted&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Downloading splits is a messy affair. The problem is that Yahoo doesn't give you&amp;nbsp; a nice comma-delimitated stream to work with. You have to parse the Html yourself (and it can be on multiple pages). At the end of the post, the overall result is kind of neat, but to get there we need a lot of busywork.&lt;/P&gt;
&lt;P&gt;First, let's define a function that constructs the correct URL to download splits from. Notice that you need to pass a page number to it.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;splitUrl ticker span page =
    &lt;SPAN style="COLOR: maroon"&gt;"http://finance.yahoo.com/q/hp?s=" &lt;/SPAN&gt;+ ticker + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;a="&lt;BR&gt;    &lt;/SPAN&gt;+ (span.Start.Month - 1).ToString() + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;b=" &lt;/SPAN&gt;+ span.Start.Day.ToString() + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;c=" &lt;BR&gt;    &lt;/SPAN&gt;+ span.Start.Year.ToString() + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;d=" &lt;/SPAN&gt;+ (span.End.Month - 1).ToString() + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;e="&lt;BR&gt;    &lt;/SPAN&gt;+ span.End.Day.ToString() + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;f=" &lt;/SPAN&gt;+ span.End.Year.ToString() + &lt;SPAN style="COLOR: maroon"&gt;"&amp;amp;g=v&amp;amp;z=66&amp;amp;y="&lt;BR&gt;    &lt;/SPAN&gt;+ (66 * page).ToString();&lt;/PRE&gt;
&lt;P&gt;The reason for this particular url format (i.e. 66 * page) is completely unknown to me. I also have the feeling that it might change in the future. Or maybe not given how many people rely on it.&lt;/P&gt;
&lt;P&gt;I then describe the driver function for loading splits:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let rec &lt;/SPAN&gt;loadWebSplitAsync ticker span page splits =
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;parseSplit text splits =
        List.append splits (parseSplits (scrapHtmlRows text)),&lt;BR&gt;                                           not(containsDivsOrSplits (scrapHtmlCells text))
    async {     
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;url = splitUrl ticker span page
        &lt;SPAN style="COLOR: blue"&gt;let! &lt;/SPAN&gt;text = loadWebStringAsync url
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;splits, beyondLastPage = parseSplit text splits
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;beyondLastPage &lt;SPAN style="COLOR: blue"&gt;then return &lt;/SPAN&gt;splits &lt;SPAN style="COLOR: blue"&gt;else&lt;BR&gt;                                 return! &lt;/SPAN&gt;loadWebSplitAsync ticker span (page + 1) splits }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This is a bit convoluted (it is an Async recursive function). Let's go through it in some detail. First there is a nested function &lt;U&gt;parseSplit&lt;/U&gt;. It takes an html string and a list of observations and returns a tuple of two elements. The first element is the same list of observations augmented with the splits found in the text. The second element is a boolean that is true if we have navigated beyond the last page for the splits.&lt;/P&gt;
&lt;P&gt;The function to test that we are beyond the last page is the following:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;containsDivsOrSplits cells =
    cells |&amp;gt; Seq.exists&lt;BR&gt;        (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(x:string) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;Regex.IsMatch(x, &lt;SPAN style="COLOR: maroon"&gt;@"\$.+Dividend"&lt;/SPAN&gt;, RegexOptions.Multiline)&lt;BR&gt;                           || Regex.IsMatch(x, &lt;SPAN style="COLOR: maroon"&gt;"Stock Split"&lt;/SPAN&gt;))  &lt;/PRE&gt;
&lt;P&gt;This function just checks if the words "Stock Split" or "Dividend" are anywhere in the table. If they aren't, then we have finished processing the pages for this particular ticker and date span.&lt;/P&gt;
&lt;P&gt;The function to extract the splits observations from the web page takes some cells (a &lt;U&gt;seq&amp;lt;seq&amp;lt;string&amp;gt;&amp;gt;)&lt;/U&gt; as input and returns an observation list. It is reproduced below:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;parseSplits rows =
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;parseRow row =
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;row |&amp;gt; Seq.exists (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(x:string) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;x.Contains(&lt;SPAN style="COLOR: maroon"&gt;"Stock Split"&lt;/SPAN&gt;))
        &lt;SPAN style="COLOR: blue"&gt;then
            let &lt;/SPAN&gt;dateS = Seq.hd row
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;splitS = Seq.nth 1 row
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;date = DateTime.Parse(dateS)
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;regex = Regex.Match(splitS,&lt;SPAN style="COLOR: maroon"&gt;@"(\d+)\s+:\s+(\d+)\s+Stock Split"&lt;/SPAN&gt;,&lt;BR&gt;                                                                   RegexOptions.Multiline)
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;newShares = shares (float (regex.Groups.Item(1).Value))
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;oldShares = shares (float (regex.Groups.Item(2).Value))
            Some({Date = date; Event = Split(newShares / oldShares)})
        &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;None
    rows |&amp;gt; Seq.choose parseRow |&amp;gt; Seq.to_list&lt;/PRE&gt;
&lt;P&gt;It just take a bunch of rows and choose the ones that contain stock split information. For these, it parses the information out of the text and creates a Split Observation out of it. I think it is intuitive what the various Seq functions do in this case. Also note my overall addiction to the pipe operator ( |&amp;gt; ). In my opinion this is the third most important keyword in F# (after 'let' and 'match').&lt;/P&gt;
&lt;P&gt;Let's now go back to the loadWebSplitAsync function and discuss the rest of it. In particular this part:&lt;/P&gt;&lt;PRE class=code&gt;async {     
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;url = splitUrl ticker span page
    &lt;SPAN style="COLOR: blue"&gt;let! &lt;/SPAN&gt;text = loadWebStringAsync url
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;splits, beyondLastPage = parseSplit text splits
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;beyondLastPage &lt;SPAN style="COLOR: blue"&gt;then return &lt;/SPAN&gt;splits &lt;SPAN style="COLOR: blue"&gt;else&lt;BR&gt;        return! &lt;/SPAN&gt;loadWebSplitAsync ticker span (page + 1) splits }&lt;/PRE&gt;
&lt;P&gt;First of all it is an Async function. You should expect some Async stuff to go on inside it. And indeed, after forming the URL in the first line, the very next line is a call to &lt;U&gt;loadWebStringAsync&lt;/U&gt;. We discussed this one in the previous installment. It just asynchronously loads a string from an URL. Notice the bang after 'let'. This is your giveaway that async stuff is being performed.&lt;/P&gt;
&lt;P&gt;The result of the async request is parsed to extract splits. Also, the &lt;U&gt;beyondLastPage&lt;/U&gt; flag is set if we have finished our work. If we have, we return the split observation list; if we haven't, we do it again incrementing the page number to load the html text from.&lt;/P&gt;
&lt;P&gt;Now that we have all the pieces in places, we can wrap up the split loading stuff inside this facade function:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;loadSplitsAsync ticker span = loadWebSplitAsync ticker span 0 []&lt;BR&gt;&lt;/PRE&gt;
&lt;P&gt;And finally put together the results of this post and the previous one with the overall function-to-rule-them-all:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;loadTickerAsync ticker span =
    async {
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;prices = loadPricesAsync ticker span
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;divs =  loadDivsAsync ticker span
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;splits = loadSplitsAsync ticker span
        &lt;SPAN style="COLOR: blue"&gt;let! &lt;/SPAN&gt;prices, divs, splits = Async.Parallel3 (prices, divs, splits)
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;prices |&amp;gt; List.append divs |&amp;gt; List.append splits
        }&lt;/PRE&gt;
&lt;P&gt;All right, that was a lot of work to get to this simple thing. This is a good entry point to our price/divs/split loading framework. It has the right inputs and outputs: it takes a ticker and a date span and returns an Async of a list of observations. Our caller can decide when he wants to execute the returned Async object.&lt;/P&gt;
&lt;P&gt;Notice that in the body of the function I call &lt;U&gt;Async.Parallel&lt;/U&gt;. This is debatable. A more flexible solution is to return a tuple containing three Asyncs (prices, divs, splits) and let the caller decide how to put them together. I decided against this for simplicity reasons. This kind of trade-off is very common in Async programming: giving maximum flexibility to your caller against exposing something more understandable.&lt;/P&gt;
&lt;P&gt;I have to admit I didn't enjoy much writing (and describing) all this boilerplate code. I'm sure it can be written in a better way. I might rewrite plenty of it if I discover bugs. I kind of like the end result though. &lt;U&gt;loadTickerAsync&lt;/U&gt; has an overall structure I'm pretty happy with.&lt;/P&gt;
&lt;P&gt;Next post,&amp;nbsp; some algorithms with our observations ...&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8959474" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Book review: The Halo Effect</title><link>http://blogs.msdn.com/lucabol/archive/2008/01/07/book-review-the-halo-effect.aspx</link><pubDate>Mon, 07 Jan 2008 22:04:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7018790</guid><dc:creator>lucabol</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/7018790.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=7018790</wfw:commentRss><description>&lt;p&gt;When I read "&lt;a href="http://www.amazon.com/Built-Last-Successful-Visionary-Companies/dp/0060566108/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1199729020&amp;amp;sr=1-1" target="_blank"&gt;Built to Last&lt;/a&gt;", "&lt;a href="http://www.amazon.com/Search-Excellence-Americas-Best-Run-Companies/dp/B0007M2K8Q/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1199729066&amp;amp;sr=1-1" target="_blank"&gt;In search of excellent&lt;/a&gt;" and "&lt;a href="http://www.amazon.com/Good-Great-Companies-Leap-Others/dp/0066620996/ref=pd_bbs_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1199729020&amp;amp;sr=1-2" target="_blank"&gt;Good to great&lt;/a&gt;" I immediately thought: "What a bunch of BS!!". But again, I think that about most business books.&lt;/p&gt; &lt;p&gt;The content of these books seemed particularly ludicrous to me. I found both logical inconsistencies and methodological flaws in their process. For example, picking successful companies &lt;em&gt;after the fact&lt;/em&gt; is analogous to picking the winners of a lottery and claim that they have exceptional skills. Betting the farm on a single concept (i.e. &lt;em&gt;Big Hairy Goal&lt;/em&gt;) is clearly the right thing when you are right, but most often than not you are wrong. What about all the companies that did that and failed? Also, &lt;em&gt;Keeping to the Core&lt;/em&gt; worked really well for Coca Cola, but really badly for Kodak.&lt;/p&gt; &lt;p&gt;These are just examples. These books are packed full of such reasonably sounding absurdities. I thought that everybody would immediately spot this. I thought that the mediocre subsequent performance of the companies originally selected as excellent would obviously demonstrate the unsoundness of such conclusion. I was very wrong. These tomes are hugely successful. People seemed to disagree with me. They really like this stuff. Given that my work and my life were not overly impacted one way or the other, I left the matter to rest.&lt;/p&gt; &lt;p&gt;And then came "&lt;a href="http://www.amazon.com/Halo-Effect-Business-Delusions-Managers/dp/0743291255/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1199729844&amp;amp;sr=1-1" target="_blank"&gt;The Halo Effect&lt;/a&gt;". It was a pleasure for me to read, as it confirmed my own ideas (confirmation bias anyone?) and added many more.&lt;/p&gt; &lt;p&gt;The title is slightly misleading. A better title would have been: "Why the idea of finding common traits among successful companies is baloney". I know, not as catchy. The catchy halo effect, mentioned in the title, is just the biggest delusion that people have about the topic.&lt;/p&gt; &lt;p&gt;I found an experiment recounted in the book to be very illuminating. They divided a set of people in multiple groups and gave each group a problem to solve. They then told half of the groups that they did a very good job and the other half that they did a very poor job. The thing is, they did so at random. They then asked people to rate the dynamics of their group on several factors. People that were told that they did a good job reported to have had wonderful dynamics: open discussions, inspired leaders, high caliber people and such. The opposite was true for the other groups.&lt;/p&gt; &lt;p&gt;It didn't matter what the actual dynamics had really been: some groups were very confrontational, others were very amicable; some were very vocal, others were very quiet. In the end, people who were told that they did good recalled the experience in positive terms. People who were told that they did poorly, recalled the experience in negative terms. Remember, good and bad outcomes were assigned randomly. Also, the results have been confirmed in several similar studies.&lt;/p&gt; &lt;p&gt;It is not a good strategy that drives performance. It is perceived performance that makes people think that they had a good strategy. This is: "The halo effect". This simple concept has dramatic repercussions.&lt;/p&gt; &lt;p&gt;First of all, it invalidates the main process used in these studies: if you use newspapers articles and managers recollection to draw conclusions, you are just piling halos over halos. People would certainly give all sort of positive attributes to companies that succeeded. They do it exactly &lt;em&gt;because&lt;/em&gt; they succeeded. And when these companies fail, they suddenly give all sort of negative attributes to them. The book is full of examples of companies that were rated as excellent when their stock price went up and terrible when their stock price went down. Nothing changed in these companies, they were still doing the same exact thing.&lt;/p&gt; &lt;p&gt;The book contains many other insights of why these 'studies' are deeply flawed. It calls them delusions. You are probably familiar with some of them if you have a scientific background: for example, Delusion of Correlation and Causality, Delusion of Single Explanation (factors are not independent), Delusion of Connecting the Winning Dots (ad hoc after the fact selection). Other delusions are specific to the analyzed domain: Delusion of Lasting Success, Delusion of Absolute Performance, Delusion of Organizational Physics.&lt;/p&gt; &lt;p&gt;In the end what should managers do? Instead of following these books's precepts, they should focus on two things: strategy and execution. Both of these things are probabilistic endeavors where the absolutely wrong measuring stick is the result that you obtain. I always found this to be a very common error people fall into at whatever level in an organization. The error is judging the soundness of a decision by its result. A decision should be judged by the soundness of the process to get to the decision and the information available &lt;em&gt;at the time the decision was taken&lt;/em&gt;. This is the only thing that is consistent with the probabilistic nature of the world we live in. The book profiles three leaders who embody this probabilistic view.&lt;/p&gt; &lt;p&gt;In summary, please go and read this book. There are many more things in it than I described in this (albeit long and boring) post.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7018790" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Books/default.aspx">Books</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>Bisection-based XIRR implementation in C#</title><link>http://blogs.msdn.com/lucabol/archive/2007/12/17/bisection-based-xirr-implementation-in-c.aspx</link><pubDate>Tue, 18 Dec 2007 02:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6793053</guid><dc:creator>lucabol</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/6793053.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=6793053</wfw:commentRss><description>&lt;P&gt;Here is a quick implementation of XIRR (using Excel nomenclature) written in C#.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Disclaimer&lt;/STRONG&gt;: this is a super simple Bisection-based implementation. People tend to prefer the Newton method, but this is simpler and works for the app I'm writing. I decided to post it because I couldn't find one on the net when I looked for it. I attached testcases to show the extent of my testing.&lt;/P&gt;
&lt;P&gt;It is called &lt;STRONG&gt;CalculateXIRR&lt;/STRONG&gt; and it is invoked by passing a list of cash flows, a tolerance and a max number of iterations.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; System;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; System.Linq;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt; = System.&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Decimal&lt;/SPAN&gt;;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; = System.&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Double&lt;/SPAN&gt;;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;FONT color=#0000ff size=2&gt;&lt;P&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;struct&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;Pair&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;T, Z&amp;gt; {&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;    &lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; Pair(T first, Z second) { First = first; Second = second; }&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;    public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;readonly&lt;/FONT&gt;&lt;FONT size=2&gt; T First;&lt;/P&gt;&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;    public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;readonly&lt;/FONT&gt;&lt;FONT size=2&gt; Z Second;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;/FONT&gt;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt; {

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; CashFlow(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt; amount, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt; date) { Amount = amount; Date = date; }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt; Amount;
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt; Date;
}

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;TKindOfResult, TValue&amp;gt; {

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; AlgorithmResult(TKindOfResult kind, TValue value) {

        Kind = kind;
        Value = value;
    }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; TKindOfResult Kind;
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; TValue Value;
}

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt; {
    ApproximateSolution,
    ExactSolution,
    NoSolutionWithinTolerance
}

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt; {

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt; CalculateXNPV(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; cfs, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; r) {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (r &amp;lt;= -1)
            r= -0.99999999; &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;// Very funky ... Better check what an IRR &amp;lt;= -100% means

&lt;/SPAN&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; cf &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; cfs
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; startDate = cfs.OrderBy(cf1 =&amp;gt; cf1.Date).First().Date
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; cf.Amount / (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;decimal&lt;/SPAN&gt;) &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Math&lt;/SPAN&gt;.Pow(1 + r, (cf.Date - startDate).Days / 365.0)).Sum(); 
    }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Pair&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt; FindBrackets(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt;&amp;gt; func, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; cfs) {

        &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;// Abracadabra magic numbers ...
&lt;/SPAN&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; maxIter = 100;
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; bracketStep = 0.5;
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;const&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; guess = 0.1;

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; leftBracket = guess - bracketStep;
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; rightBracket = guess + bracketStep;
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; iter = 0;

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;while&lt;/SPAN&gt; (func(cfs, leftBracket) * func(cfs, rightBracket) &amp;gt; 0 &amp;amp;&amp;amp; iter++ &amp;lt; maxIter) {

            leftBracket -= bracketStep;
            rightBracket += bracketStep;
        }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (iter &amp;gt;= maxIter)
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Pair&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt;&amp;gt;(0, 0);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Pair&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt;(leftBracket, rightBracket);
    }
   
    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;// From "Applied Numerical Analyis" by Gerald
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt; Bisection(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt;&amp;gt; func, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Pair&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt; brackets, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; tol, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; maxIters) {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; iter = 1;

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Money&lt;/SPAN&gt; f3 = 0;
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; x3 = 0;
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; x1 = brackets.First;
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; x2 = brackets.Second;

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;do&lt;/SPAN&gt; {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; f1 = func(x1);
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; f2 = func(x2);

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (f1 == 0 &amp;amp;&amp;amp; f2 == 0)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.NoSolutionWithinTolerance, x1);
            
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (f1 * f2 &amp;gt; 0)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArgumentException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"x1 x2 values don't bracket a root"&lt;/SPAN&gt;);

            x3 = (x1 + x2) / 2;
            f3 = func(x3);

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (f3 * f1 &amp;lt; 0)
                x2 = x3;
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else
&lt;/SPAN&gt;                x1 = x3;

            iter++;

        } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;while&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Math&lt;/SPAN&gt;.Abs(x1 - x2)/2 &amp;gt; tol &amp;amp;&amp;amp; f3 != 0 &amp;amp;&amp;amp; iter &amp;lt; maxIters);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (f3 == 0)
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ExactSolution, x3);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Math&lt;/SPAN&gt;.Abs(x1 - x2) / 2 &amp;lt; tol)
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, x3);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (iter &amp;gt; maxIters)
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.NoSolutionWithinTolerance, x3);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"It should never get here"&lt;/SPAN&gt;);
    }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt;&amp;gt; CalculateXIRR(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; cfs, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; tolerance, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; maxIters) {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; brackets = FindBrackets(CalculateXNPV, cfs);
        
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (brackets.First == brackets.Second)
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmResult&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt;&amp;gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.NoSolutionWithinTolerance, brackets.First);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; Bisection(r =&amp;gt; CalculateXNPV(cfs,r), brackets, tolerance, maxIters);
    }
}&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;STRONG&gt;// TESTS&lt;/STRONG&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; Microsoft.VisualStudio.TestTools.UnitTesting;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; System.Collections.Generic;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; System;
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Rate&lt;/SPAN&gt; = System.&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Double&lt;/SPAN&gt;;

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;namespace&lt;/SPAN&gt; TimeLineTest
{
    [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestClass&lt;/SPAN&gt;()]
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;AlgorithmsTest&lt;/SPAN&gt; {

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; cfs = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10000, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(2750, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,3,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(4250, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,10,30)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(3250, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2009,2,15)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(2750, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2009,4,1))
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; bigcfs = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2002,1,2)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(20, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2003,1,3))
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; negcfs = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-1, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2002,1,2)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(1, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2003,1,3))
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; samedaysamecfs = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; samedaydifferentcfs = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(100, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; bigratecfs = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(20, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,5,30)),
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; zeroRate = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2000,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(10, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2003,1,1)),
                };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; doubleNegative = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10000, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(2750, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,3,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-4250, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,10,30)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(3250, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2009,2,15)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(2750, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2009,4,1))
            };

        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;&amp;gt; badDoubleNegative = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;[] {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-10000, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,1,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(2750, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,3,1)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-4250, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2008,10,30)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(3250, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2009,2,15)),
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;CashFlow&lt;/SPAN&gt;(-2750, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;(2009,4,1))
            };


        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt; r = 0.09;
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt; tolerance = 0.0001;
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; maxIters = 100;

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestContext&lt;/SPAN&gt; testContextInstance;

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestContext&lt;/SPAN&gt; TestContext {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; testContextInstance;
            }
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;set&lt;/SPAN&gt; {
                testContextInstance = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;value&lt;/SPAN&gt;;
            }
        }

        [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestMethod&lt;/SPAN&gt;()]
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt; CalculateXNPV() {

            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(2086.6476020315416570634272814M, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXNPV(cfs, r));
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(-10.148147600710372651326920258M, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXNPV(negcfs, 0.5));
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(4.9923725815954514810351876895M, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXNPV(bigcfs, 0.3));
        }

        [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestMethod&lt;/SPAN&gt;]
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt; FindBrackets() {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; brackets = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.FindBrackets(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXNPV, cfs);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.IsTrue(brackets.First &amp;lt; 0.3733 &amp;amp;&amp;amp; brackets.Second &amp;gt; 0.3733);

            brackets = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.FindBrackets(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXNPV, bigcfs);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.IsTrue(brackets.First &amp;lt; 0.5196 &amp;amp;&amp;amp; brackets.Second &amp;gt; 0.5196);

            brackets = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.FindBrackets(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXNPV, negcfs);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.IsTrue(brackets.First &amp;lt; -0.6059 &amp;amp;&amp;amp; brackets.Second &amp;gt; -0.6059);
        }

        [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestMethod&lt;/SPAN&gt;]
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt; XIRRTest() {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(cfs, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(0.3733, irr.Value, 0.001);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(bigcfs, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(0.5196, irr.Value, 0.001);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(negcfs, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(-0.6059, irr.Value, 0.001);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(samedaysamecfs, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.NoSolutionWithinTolerance, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(samedaydifferentcfs, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.NoSolutionWithinTolerance, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(bigratecfs, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(4.40140, irr.Value, 0.001);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(zeroRate, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(0, irr.Value, 0.001);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(doubleNegative, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(-0.537055, irr.Value, 0.001);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.ApproximateSolution, irr.Kind);

            irr = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Algorithms&lt;/SPAN&gt;.CalculateXIRR(badDoubleNegative, tolerance, maxIters);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ApproximateResultKind&lt;/SPAN&gt;.NoSolutionWithinTolerance, irr.Kind);
        }
    }
}
&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6793053" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>Parsing QIF Quicken files in C#</title><link>http://blogs.msdn.com/lucabol/archive/2007/08/31/parsing-qif-quicken-files-in-c.aspx</link><pubDate>Fri, 31 Aug 2007 23:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4675458</guid><dc:creator>lucabol</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/4675458.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=4675458</wfw:commentRss><description>&lt;P&gt;I'm slightly prouder of the structure of this code than&amp;nbsp;the&amp;nbsp;one in &lt;A href="http://blogs.msdn.com/lucabol/archive/2007/08/30/retrieve-prices-dividends-and-splits-for-a-stock-in-c.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2007/08/30/retrieve-prices-dividends-and-splits-for-a-stock-in-c.aspx"&gt;the previous blog post&lt;/A&gt;. You can simply inherit from QIFParserBase and override a couple of abstract methods to customize the behavior. Still, I just tested it on a couple of test QIF files. It is not production quality at all.&lt;/P&gt;
&lt;P&gt;Notice that I don't even have Quicken. I'm producing these test file with &lt;A href="http://www.fundmanagersoftware.com/" mce_href="http://www.fundmanagersoftware.com/"&gt;FundManager&lt;/A&gt;, which I use for my investments. If your software generates QIF files differently, than you have to modify the code. It shouldn't be too hard.&lt;/P&gt;
&lt;P&gt;It works with &lt;A href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;VS 2008 beta 2&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4675458" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/4675458.ashx" length="711685" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>Retrieve prices, dividends and splits for a stock in C#</title><link>http://blogs.msdn.com/lucabol/archive/2007/08/30/retrieve-prices-dividends-and-splits-for-a-stock-in-c.aspx</link><pubDate>Thu, 30 Aug 2007 23:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4654000</guid><dc:creator>lucabol</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/4654000.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=4654000</wfw:commentRss><description>&lt;P&gt;I wrote this code very quickly and I'm kind of ashamed of it, but it gets the job done (I think). You need the HTML Agility Pack for the stock splits retrieving code. You can download it from &lt;A class="" href="http://www.codeplex.com/htmlagilitypack/Release/ProjectReleases.aspx?ReleaseId=272" mce_href="http://www.codeplex.com/htmlagilitypack/Release/ProjectReleases.aspx?ReleaseId=272"&gt;here&lt;/A&gt;&amp;nbsp;or you can simply comment out the code. I wrote it against &lt;A class="" href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;Visual Studio 2008 beta 2&lt;/A&gt;, but it should be trivial to port it to previous versions.&lt;/P&gt;
&lt;P&gt;You run it from a command window like this: "priceretriever msft 1/1/1990 2/3/2003". The last two parameters are optional and default to 1/1/1980 and today.&lt;/P&gt;
&lt;P&gt;Enjoy.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4654000" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/4654000.ashx" length="50909" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>A financial education (my ideas)</title><link>http://blogs.msdn.com/lucabol/archive/2007/04/20/a-financial-education-my-ideas.aspx</link><pubDate>Fri, 20 Apr 2007 21:55:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2210529</guid><dc:creator>lucabol</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/2210529.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=2210529</wfw:commentRss><description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;When I came to US, I wanted to get an introduction on personal finance. I needed to know what to insure, when, how to buy an house and all this sort of basic things. At the time I read &lt;a href="http://www.amazon.com/Personal-Finance-Dummies-Eric-Tyson/dp/0764552317"&gt;Personal Finance for Dummies&lt;/a&gt;. I then discovered that very many US folks don’t know about these things either and I found myself recommending this simple book to plenty of people. You can find it for a few bucks in used book-stores. It might be too basic for you, but again, it might not. &lt;p&gt;Investment is a subset of personal finance and by far not the most important one (the most important probably being how to save the most – which means paying you first). Nevertheless, understanding how to invest the money that you do save is important. The following represents a very condensed summary of my views on the topic. There are dozens of others very good books that I could have suggested instead. &lt;p&gt;The first thing I would do is to get a decent understanding of the relationship between risk and reward that is so pervasive in financial markets. Good books on the topic are &lt;a href="http://www.amazon.com/Four-Pillars-Investing-Building-Portfolio/dp/0071385290/ref=pd_bbs_sr_2/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177084673&amp;amp;sr=1-2"&gt;The Four Pillars of Investing&lt;/a&gt; or &lt;a href="http://www.amazon.com/Random-Walk-Down-Wall-Street/dp/0393062457/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177084725&amp;amp;sr=1-1"&gt;A Random Walk Down Wall Street&lt;/a&gt;. A new book that I haven’t read, but suspect quite good (and short) is &lt;a href="http://www.amazon.com/Little-Book-Common-Sense-Investing/dp/0470102101/ref=pd_bbs_3/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177084725&amp;amp;sr=1-3"&gt;The Little Book of Common Sense Investing&lt;/a&gt;. This books try to convince you that it is not possible to ‘beat the market’ and the best you can do is to decide on an asset allocation that represents your risk/reward profile. If you believe that, then it is worth getting to the next step by understanding the concept of mean variance optimization. Good medium level books on that are &lt;a href="http://www.amazon.com/About-Asset-Allocation-Richard-Ferri/dp/0071429581/ref=sr_1_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177085023&amp;amp;sr=1-1"&gt;All About Asset Allocation&lt;/a&gt; and the &lt;a href="http://www.amazon.com/Intelligent-Asset-Allocator-Portfolio-Maximize/dp/0071362363/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177085117&amp;amp;sr=1-1"&gt;Intelligent Asset Allocator&lt;/a&gt;. There are advanced books on the topic as well, but I won’t mention them here. An advanced service in this area is &lt;a href="http://www.indexinvestor.com/"&gt;IndexInvestor&lt;/a&gt;. &lt;p&gt;With time, analyzing the amount of evidence, I came to believe that it is indeed possible to beat the market. But it is not easy and 99% of the methods out there are bunk. Moreover it does require a lot of work and a certain passion for the investment field. So, if you don’t have time or passion you are probably better off sticking to the strategies described in the aforementioned books. If you have a small amount of time, but you still want to try and beat the market, an avenue open to you is the selection of mutual funds. Even then, you need to have some strong held view of which kind of investment strategy and character traits are more likely to bring about superior investment results so that you can pick the right manager (or most likely set of managers) for your money. I describe below what are my personal views on the matter. They are all very debatable. A good service that gives sane information about mutual funds, how to select them and assemble them in your portfolio is &lt;a href="http://www.morningstar.com/"&gt;Morningstar&lt;/a&gt;. I certainly suggest you subscribe to it, if you invest in mutual funds. &lt;p&gt;A time honored and generally successful stock picking method is value investing. The father of value investing is Benjamin Graham and two books written by him are everlasting classics of investment. They are &lt;a href="http://www.amazon.com/Intelligent-Investor-Collins-Business-Essentials/dp/0060555661/ref=pd_bbs_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177086377&amp;amp;sr=1-1"&gt;The Intelligent Investor&lt;/a&gt; and &lt;a href="http://www.amazon.com/Security-Analysis-Benjamin-Graham/dp/0071448209/ref=sr_1_3/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177086459&amp;amp;sr=1-3"&gt;Security Analysis&lt;/a&gt;. Aficionados disagree on which releases are the best, the links provided represent my opinion. Please start with the former, as the latter is long and complex. They are both quite dated, but plenty of folks believe that not much has been discovered after their publication. I disagree. Another, maybe better, introductory book is &lt;a href="http://www.amazon.com/Little-Book-Value-Investing/dp/0470055898/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177087947&amp;amp;sr=1-1"&gt;The Little Book of Value Investing&lt;/a&gt;. There are wonderful mutual funds out there that invest in the spirit of value investing. Among others, I like &lt;a href="http://www.thirdavenuefunds.com/taf/"&gt;Third Avenue&lt;/a&gt;, &lt;a href="http://www.pinnaclevaluefund.com/"&gt;Pinnacle&lt;/a&gt; and &lt;a href="http://www.roycefunds.com/"&gt;Royce&lt;/a&gt;. &lt;p&gt;Warren Buffett expanded on Graham by putting more emphasis on the quality of the companies he invests in instead of mostly the price. A good book describing his approach is &lt;a href="http://www.amazon.com/Warren-Buffett-Way-Second/dp/0471743674/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177086947&amp;amp;sr=1-1"&gt;The Warren Buffett Way&lt;/a&gt;. You can obviously go and read Buffett’s letters directly &lt;a href="http://www.berkshirehathaway.com/"&gt;here&lt;/a&gt;, but that is better suited as a second step after reading Graham or the aforementioned book. There are plenty of disciples of this method of investing. If you want to have some of them managing your money, my preferred are &lt;a href="http://www.longleafpartners.com/"&gt;Longleaf&lt;/a&gt;, &lt;a href="http://www.fairholmefunds.com/"&gt;Fairholme&lt;/a&gt;, &amp;nbsp;&lt;a href="http://www.weitzfunds.com/"&gt;Weitz&lt;/a&gt; and &lt;a href="http://www.clipperfund.com/"&gt;Clipper&lt;/a&gt; among others. A good service that suggest stocks based on this style of investing is the stock section of &lt;a href="http://www.morningstar.com/"&gt;Morningstar&lt;/a&gt;. You also can invest in brk.b directly to buy the services of Buffett himself. I personally believe it is quite undervalued at the current juncture. &lt;p&gt;In the past 15 years or so, there has been a lot of interesting work done on purely quantitative investing systems. They have several advantages over judgment based ones (essentially the human brain is not wired correctly to fight a complex adaptive system as the stock market). There are two categories of systems I feel I can recommend in this area: fundamental based and momentum based. This is a very complex mathematical topic at the high end, but it is possible to get a profitable understanding of it by reading &lt;a href="http://www.amazon.com/What-Works-Street-James-OShaughnessy/dp/0071452257/ref=pd_bbs_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177087865&amp;amp;sr=1-1"&gt;WWOWS&lt;/a&gt; and &lt;a href="http://www.amazon.com/Little-Book-That-Beats-Market/dp/0471733067/ref=pd_bbs_3/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177087865&amp;amp;sr=1-3"&gt;The Little Book That Beats The Market&lt;/a&gt;. These books describe fundamental based systems, for a purely momentum based one the best bet is &lt;a href="http://www.fundx.com/"&gt;FundX&lt;/a&gt;. The web site is not too informative, but if you go to the library and ask the librarian they have a little book written by the FundX guys that describe their system in a great level of detail. The best quantitative mutual funds I can think of are from &lt;a href="http://www.bridgewayfunds.com/"&gt;Bridgeway&lt;/a&gt; (there are also others). Like all the other funds I suggested, they are managed by wonderful people that takes the shareholders interests very seriously. &lt;p&gt;You can also try to tactically switch between different asset classes (i.e. stocks and cash) based on some indicators. I have mixed feelings about this. It might work, but it is debatable how much do you really gain by doing it, after considering taxes and commissions. It is something I could investigate more. Two good books on the matter are &lt;a href="http://www.amazon.com/Only-Three-Questions-That-Count/dp/047007499X/ref=sr_1_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177088936&amp;amp;sr=1-1"&gt;The Only Three Questions That Count&lt;/a&gt; and &lt;a href="http://www.amazon.com/Research-Driven-Investor-Information-Investment/dp/007135462X/ref=pd_bbs_sr_1/103-2224493-9497443?ie=UTF8&amp;amp;s=books&amp;amp;qid=1177088971&amp;amp;sr=1-1"&gt;The Research Driven Investor&lt;/a&gt;. Good mutual funds that do this (with very different risk profiles) are &lt;a href="http://www.hussmanfunds.com/"&gt;Hussman&lt;/a&gt; and &lt;a href="http://www.cgmfunds.com/"&gt;CGM&lt;/a&gt;. &lt;p&gt;A couple of notes to close. Reading these books is an exercise in critical thinking. There are huge amount of contradictory statements on very basic and important concepts. The only way around it is to do your own research and make up your own mind. Even then, you won’t be in a situation of perfect information/clear decision. This cannot be so because the market changes constantly. As soon as something is discovered it gets priced in. This is why it is such an exciting field of study (for some people at least). Also I have my own key rule about investing: I never invest in anything that I don’t understand completely. Every time I’ve done that, I've regretted it. If this is the only thing that you remember after reading this, I’ll be very happy.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2210529" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Books/default.aspx">Books</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>A good Emerging Market fund</title><link>http://blogs.msdn.com/lucabol/archive/2007/02/02/a-good-emerging-market-fund.aspx</link><pubDate>Fri, 02 Feb 2007 21:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1584236</guid><dc:creator>lucabol</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/1584236.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=1584236</wfw:commentRss><description>&lt;P&gt;If you are looking for a good fund for this corner of your portfolio, you might want to consider Eaton Vance Structured Emerging Mkt (EAEMX). There is also a much cheaper version (EITEX), but it is open just to folks with a financial advisor.&lt;/P&gt;
&lt;P&gt;It is a&amp;nbsp;mechanical fund. Here is how their strategy works (as far as I understand it):&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;They divide EM market countries&amp;nbsp;in 4 categories, they assign a weight&amp;nbsp;to each category (I.E. 20% to tier1, 30% to tier2 etc...)&lt;/LI&gt;
&lt;LI&gt;For each category they equal weight each country in the category (I.E. in tier1 equal weight Russia, Mexico, etc...)&lt;/LI&gt;
&lt;LI&gt;For each country they equal weight each sector&lt;/LI&gt;
&lt;LI&gt;They actively harvest tax losses&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The end result is as follows:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Smaller country have more weight than in a normal Em.Mkt. fund. This is good because:&lt;/LI&gt;
&lt;OL&gt;
&lt;LI&gt;Smaller markets have had higher returns in the past&lt;/LI&gt;
&lt;LI&gt;Smaller markets&amp;nbsp;are less correlated than large markets both among themselves and against the SP500&lt;/LI&gt;&lt;/OL&gt;
&lt;LI&gt;Equal weighting the sectors has the following positive effects:&lt;/LI&gt;
&lt;OL&gt;
&lt;LI&gt;You get more exposure to sectors, like Services, that are going to benefit from economic growth&lt;/LI&gt;
&lt;LI&gt;You avoid the 'commodity effect': the tendency of Em.Markets to fall when commodities prices fall because such a large slice of their economy is based on it&lt;/LI&gt;&lt;/OL&gt;
&lt;LI&gt;It is extremely tax efficient because:&lt;/LI&gt;
&lt;OL&gt;
&lt;LI&gt;The mechanical strategy lends itself to low turnover&lt;/LI&gt;
&lt;LI&gt;They actively harvest tax losses&lt;/LI&gt;&lt;/OL&gt;&lt;/OL&gt;
&lt;P&gt;In essence they maximize the positive effects of diversification and tax efficiency, which are very stable effects. They are mathematically provable :-) The real time results confirm the theory as this has been one of the best performing Em. Markets funds with the lowest standard deviation and best tax efficiency. No-one knows what the future holds, but there is a good chance that this will continue to be the case.&lt;/P&gt;
&lt;P&gt;I don't own it currently because I don't like the high fees, but the strategy makes so much sense that I might end up buying into it.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1584236" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>A trading/portfolio management Excel Add-in based on the books by Ralph Vince</title><link>http://blogs.msdn.com/lucabol/archive/2007/01/04/a-trading-portfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.aspx</link><pubDate>Fri, 05 Jan 2007 01:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1412946</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/1412946.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=1412946</wfw:commentRss><description>&lt;P&gt;I like to write code and I still manage to do it even now that it is not my primary job. I never post the things that I write because I don't want to maintain them.&amp;nbsp;Lately &lt;A class="" href="http://blogs.msdn.com/charlie/" target=_blank mce_href="http://blogs.msdn.com/charlie/"&gt;Charlie&lt;/A&gt;&amp;nbsp;convinced me that I don't have to do that. I can just throw the code out, without much preparation or implicit contract of perpetual maintenance.&lt;/P&gt;
&lt;P&gt;This one is an Excel add-in that adds functions to Excel to analyze your trading and manage your portfolio. Notice that I'm not a professional trader or statistician, so the whole thing could be wrong, buggy or conceptually absurd. Probably it is all of the above.&lt;/P&gt;
&lt;P&gt;I used the extremely good&amp;nbsp;&lt;A class="" href="http://exceldna.typepad.com/" target=_blank mce_href="http://exceldna.typepad.com/"&gt;ExcelDna&lt;/A&gt; to write the add-in. You need to download it and follow the instructions in &lt;EM&gt;HowToInstall.txt&lt;/EM&gt; on the attached zip file to use it. I based the formulas mainly on the work of &lt;A class="" href="http://www.amazon.com/s/103-4348138-5739032?ie=UTF8&amp;amp;index=books&amp;amp;rank=-relevance%2C%2Bavailability%2C-daterank&amp;amp;field-author-exact=Vince%2C%20Ralph" target=_blank mce_href="http://www.amazon.com/s/103-4348138-5739032?ie=UTF8&amp;amp;index=books&amp;amp;rank=-relevance%2C%2Bavailability%2C-daterank&amp;amp;field-author-exact=Vince%2C%20Ralph"&gt;Ralph Vince&lt;/A&gt;. Please buy and read his books on money management as they are wonderful.&lt;/P&gt;
&lt;P&gt;On the statistics side: I made up the "Downside correlation coefficient", I have no idea if it is statistically sound.&lt;BR&gt;On the technical side:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;I haven't optimized the algos at all. I.E. I'm sure there is a way to calculate the standard deviation without navigating the array twice, but I didn't bother to look. They end up being fast enough anyhow (apart from the Monte Carlo related functions that I should investigate).&lt;/LI&gt;
&lt;LI&gt;I haven't organized the code correctly. It needs to be rewritten now that I partially know what I'm doing.&lt;/LI&gt;
&lt;LI&gt;I haven't used LINQ. It will be a lot of fun for me to rewrite the code to be more OO and to use LINQ in the process.&lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;I plan to implement OptimalF for a normal distribution and Efficient Frontier calculations in the future. I have no idea when.&lt;/P&gt;
&lt;P mce_keep="true"&gt;I also have some other projects that might be interesting to share (I.E. a blackjack simulator that you can use to try the result of different strategies inspired by &lt;A class="" href="http://www.amazon.com/Blackjack-Attack-Playing-Pros-Way/dp/0910575207/sr=8-1/qid=1167952522/ref=pd_bbs_sr_1/103-4348138-5739032?ie=UTF8&amp;amp;s=books" target=_blank mce_href="http://www.amazon.com/Blackjack-Attack-Playing-Pros-Way/dp/0910575207/sr=8-1/qid=1167952522/ref=pd_bbs_sr_1/103-4348138-5739032?ie=UTF8&amp;amp;s=books"&gt;Blackjack Attack&lt;/A&gt;).&lt;/P&gt;
&lt;P mce_keep="true"&gt;This is the list of Excel functions that you get with this add-in. They ends up in a Trading category in the list of functions on the "Insert Function" Excel dialog:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 0.5in"&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;AnnualizeRet(double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;AnnualizeStdevp(double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;AnnualStdevpParam(double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;ArithMean(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;AutoCorrel(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;AvgLoss(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;AvgWin(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;Chebyshev(double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;Correlat(object[,], object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;Describe(object)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;DownCorrelat(object[,], object[,], double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;DownStdevp(object[,], double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;EGM(double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;EGM2(double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;GM(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;Kelly(double, double) TradingLibrary.Losses(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MaxDD(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MaxDDFromEq(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MaxLoss(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MaxNegRun(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MaxWin(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MCMaxDD(object[,], double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;MCOptimalF(object[,], double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;OptimalF(object[,], double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;OptimalFArray(object[,], double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;OptimalPos(double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;PortAnnualGM(double, double, double, double, double, double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;PortAnnualTaxGM(double, double, double, double, double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;PortAnnualTaxGMGivenTrades(object[,], double, double, double, double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;PortStdevp(double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;PRR(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;PRRParam(double, double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;RealReturn(double, double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;RunTest(object[,])&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;SharpeRatio(double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;SortinoRatio(double, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;Stdevp2(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN lang=FR style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;TWR(object[,], double, double, object, double, double)&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;Wins(object[,])&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 0.5in"&gt;&lt;FONT face=Tahoma size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;&lt;A href="http://www.dotnetkicks.com/kick/?url=http://blogs.msdn.com/lucabol/archive/2007/01/04/a-trading-portfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.aspx"&gt;&lt;IMG alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://blogs.msdn.com/lucabol/archive/2007/01/04/a-trading-portfolio-management-excel-add-in-based-on-the-books-by-ralph-vince.aspx" border=0&gt;&lt;/A&gt; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1412946" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/1412946.ashx" length="668944" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>To rent or to buy a house, some more evidence of my unpopular thesis ...</title><link>http://blogs.msdn.com/lucabol/archive/2005/03/09/391038.aspx</link><pubDate>Wed, 09 Mar 2005 20:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:391038</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/391038.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=391038</wfw:commentRss><description>&lt;p&gt;I discussed this topic in a previous post &lt;A href="http://blogs.msdn.com/lucabol/archive/2004/07/30/202394.aspx"&gt;http://blogs.msdn.com/lucabol/archive/2004/07/30/202394.aspx&lt;/a&gt;&amp;nbsp;and I received a number of emails telling me how crazy I was even speculating that, at the current juncture, it may be more convinient to rent than to buy a house.&lt;/p&gt; &lt;p&gt;This week The Economist runs a piece where they make the same exact claim. House prices are so high and rents are so low all over the world that renting might, indeed, be&amp;nbsp;better. Even considering the low interest rate environment, it would seem that the&amp;nbsp;house prices are out of&amp;nbsp;step with&amp;nbsp;reality, very much as equities where in the 90's.&lt;/p&gt; &lt;p&gt;It is all a game of expectations. The harder things to estimate are the future house price gain and the interest rate/gain you can get by investing the difference between rent and mortgage payments. By using difference estimates, you get difference answers. My own opinion is that the probabilities weight against buying an house at this time. Here is a spreadsheet to help you out: &lt;A href="http://blogs.msdn.com/lucabol/archive/2004/08/18/216662.aspx"&gt;http://blogs.msdn.com/lucabol/archive/2004/08/18/216662.aspx&lt;/a&gt;&amp;nbsp;.&lt;/p&gt; &lt;p&gt;There are other considerations: I bought a house not to get killed by my wife :) But I've been able to limit the expense and I avoided investing more money in real estate.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=391038" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>"Rent or buy" spreadsheet</title><link>http://blogs.msdn.com/lucabol/archive/2004/08/18/216662.aspx</link><pubDate>Wed, 18 Aug 2004 19:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:216662</guid><dc:creator>lucabol</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/216662.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=216662</wfw:commentRss><description>&lt;p&gt;Someone&amp;nbsp;asked me for the spreadsheet I used for the&amp;nbsp;calculations in my previous posts.&amp;nbsp; &lt;a href="http://www.duncanmackenzie.net/rentorbuy.zip"&gt;Here&lt;/a&gt; you have it. The data doesn't reflect my current situation.&lt;/p&gt; &lt;p&gt;Feel free to use it with your own numbers (and tell me of any bug).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=216662" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>I'm buying a house...</title><link>http://blogs.msdn.com/lucabol/archive/2004/08/02/206086.aspx</link><pubDate>Mon, 02 Aug 2004 19:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:206086</guid><dc:creator>lucabol</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/206086.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=206086</wfw:commentRss><description>&lt;P&gt;I think I've been misinterpreted in my previous posts. I'm not suggesting that renting is better than owning.&amp;nbsp;You have&amp;nbsp;to run your numbers and make your own choice. There are many assumptions to consider (financial and not). The not financial ones often are more important. You have to run your numbers, but&amp;nbsp;in general renting looks better if:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;You cannot buy ( :) ) and/or&lt;/LI&gt;
&lt;LI&gt;You plan to stay in a place for a short time and/or&lt;/LI&gt;
&lt;LI&gt;You believe houses are vastly overpriced in your area and they'll return will be negative for a while and/or&lt;/LI&gt;
&lt;LI&gt;You don't want the psychological part of having a house (maintenance, tax payments, ...)&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In my case the most worrisome&amp;nbsp;scenario is&amp;nbsp;3.&lt;/P&gt;
&lt;P&gt;Back to our situation, we are buying a house for the pleasure of living in a particular location. Financially it is an OK transaction (fair price, I think). &lt;/P&gt;
&lt;P&gt;I'll probably post a little rent-buy spreadsheet as soon as I have time to refine it.&lt;/P&gt;
&lt;P&gt;Thanks for all the good comments.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=206086" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>To rent or to buy a house??</title><link>http://blogs.msdn.com/lucabol/archive/2004/07/30/202394.aspx</link><pubDate>Fri, 30 Jul 2004 18:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:202394</guid><dc:creator>lucabol</dc:creator><slash:comments>27</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/202394.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=202394</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Spurred by some comments to a previous post I quickly run these numbers. They analyze the case of house price not rising in the next five years. I&amp;#8217;ll take more time to check them if I really get to a point of deciding, but they should be correct.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;This data (fairly typical in my area):&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Home price: $200,000&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Down payment: $0&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Interest rate: 6%&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Monthly mortgage: 1210&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Rent: 750&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Annual gains on investments: 6%&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;If I run this for 5 years and house appreciation 0% I get:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;$33,043 on investing the rent-mortgage difference&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;$30,609 on paying the mortgage (equity accumulation + tax savings at 28%)&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;If we assume to put down 20% to buy the house then the numbers are even worse:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;$83,542 on investing the down payment and the rent-mortgage difference&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;$67,548 on paying the mortgage (equity accumulation + tax savings at 28%)&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;There are other things to consider: house repairs for houses, annual raises in rent, etc&amp;#8230; etc&amp;#8230;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Are those assumptions reasonable? So it is better to rent than to buy? Well, over the long term houses do tend to appreciate and the more leverage you have, the more you reap the benefits. Over the short term, run your numbers. There are so many assumptions you can make, that it become almost a personal opinion what is best.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;EM&gt;Running the numbers help you in making sure than it is at least an informed opinion. It makes your assumptions explicit&lt;/EM&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=202394" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item><item><title>My quest for a new home...</title><link>http://blogs.msdn.com/lucabol/archive/2004/07/29/200771.aspx</link><pubDate>Thu, 29 Jul 2004 16:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:200771</guid><dc:creator>lucabol</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/200771.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=200771</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;I&amp;#8217;m refining my understanding of how to value residential properties. There is this rule of thumb: buy when you can get a rent for the property which is at least 1.2% of the property price (or in another form, when the home price is 7x the annual rent). This is an approx for a more formal spreadsheet (which I have).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;This is fine and dandy, but in the area I&amp;#8217;m interested in a typical one bedroom condo sells for around $200,000-300,000 and you can get a monthly rent of $1,000-1,300. This doesn&amp;#8217;t work by a very large factor. Hmmm&amp;#8230;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Let&amp;#8217;s change the target to a cheaper area. Now I can probably get around $800 monthly. To make things work I need to find a condo for $67,200. Not an easy task, almost impossible.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;It looks like for me it is hard to find a house in an area I like and at the same time make a good investment (unless the market bails me out by raising home prices at a high rate). There is quite a large disconnect between house prices and rents now. Maybe the residential market is really on the brink of a fall&amp;#8230; Time to rent again?&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=200771" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category></item></channel></rss>