<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
<title>OpenGamma Blog</title>
<link>http://www.opengamma.com/blog</link>
<description>News, announcements and talk on risk management, financial analytics and open source by the OpenGamma team.</description>
<pubDate>2012-05-10T00:00:00</pubDate>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/OpenGammaBlog" /><feedburner:info uri="opengammablog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
<title>Some Insight into the OpenGamma Recruitment Process</title>
<description>&lt;p&gt;When OpenGamma was started by &lt;a href="http://www.opengamma.com/about/people/kirk-wylie"&gt;Kirk Wylie&lt;/a&gt;, &lt;a href="http://www.opengamma.com/about/people/elaine-mcleod"&gt;Elaine McLeod&lt;/a&gt; and me, our approach to recruitment was primarily driven by our own recruitment experiences. We were all recruited into the expectations of the Hedge Fund environment: operating in a high-pressure environment with an extremely high expected level of professionalism and technical excellence. Later on, we were also involved in interviewing many other candidates for roles operating alongside us.&lt;/p&gt;
&lt;p&gt;In this post, I'm going to describe the evolution of the recruitment process at OpenGamma and what it looks like today, specifically focusing on Platform Development roles.&lt;/p&gt;
&lt;h2&gt;How our recruitment process has evolved over time&lt;/h2&gt;
&lt;p&gt;The first interviews at OpenGamma were based upon the previous ‘Hedge Fund’ model. To some degree, with hindsight, our interviews tended to be rather too close to a process of attrition. In a desire to both put the candidate under pressure to see how they operated in a high-stress situation, and to maximise the use of a candidate's time (taking time off work can be difficult to repeat for a candidate), we tended to do ‘marathon’ interviews of 5-6 hours, with staff members each taking an hour-long slot. We also early on had a policy of every team member interviewing new candidates.&lt;/p&gt;
&lt;p&gt;This process was not sustainable. We first introduced phone interviews, so we didn’t waste our time and the time of candidates who we didn’t believe were a good fit. After the team had expanded to a certain point, we could also no longer sustain the policy of every team member interviewing new candidates. There were a couple of reasons for this. Firstly, the sheer number of people involved became unmanageable. We began to double up staff in interviews, with typically one person leading the interview and another more passive. This meant we could get more people in the process. But every time you add a person to the process, it becomes harder to accept a candidate (an important part of our interview methodology is that every interviewer can give a “No” to any candidate; we always ask the interviewer to justify this decision, but at the end of the day the people who are interviewing will have to work with the candidate and they need to feel comfortable with working with him or her for a long time). Even a really excellent candidate has a small probability of being rejected by a seemingly rational interviewer. When you multiply these probabilities by 6, 8 or even 10, you increase the risk of rejecting perfectly reasonable candidates.&lt;/p&gt;
&lt;p&gt;This did in fact happen on at least one occasion. After rejecting one candidate, they kept coming to mind and no one could give a good reason why they were rejected - so six months later, we offered them the job (they’ve now been with us for over a year).&lt;/p&gt;
&lt;p&gt;Lastly, we stopped the really long interviews in most cases. Part of our reason for trying to perform interviews in one day was because we had ourselves been irritated by the two, three or even more interviews typically required in the financial industry’s recruitment process. It can be tough for a candidate to get that much time off work without arousing suspicion. We therefore still give some candidates the option of packing the interviews together, particularly if they have travelled from further afield to attend.&lt;/p&gt;
&lt;p&gt;We also weren’t sure that screening out people who weren’t capable of operating in a super high-pressure environment was necessarily always a great idea. OpenGamma is not a hedge fund after all, and we pride ourselves on giving employees a pleasant working environment, with flexible working hours and so on. So while we do need people who can think fast on their feet and work to fix customer problems quickly, we also have room for those who are excellent, but perhaps look to longer term issues like system design and evolution rather than quick fixes.&lt;/p&gt;
&lt;h2&gt;...And what it looks like today&lt;/h2&gt;
&lt;p&gt;So, after that process of evolution, we’ve fallen into a predictable pattern:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CVs &lt;/strong&gt;come to us via either:
&lt;ul&gt;
&lt;li&gt;One of the few recruitment agents on our approved list (which is very short, and we are not looking to add to this list at the moment).&lt;/li&gt;
&lt;li&gt;Directly emailed to jobs at opengamma dot com.&lt;/li&gt;
&lt;li&gt;Events such as &lt;a href="http://siliconmilkroundabout.com/" target="_blank"&gt;Silicon Milkroundabout&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Personal introductions and recommendations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The appropriate head of the team will review CVs to provide a &lt;strong&gt;short list&lt;/strong&gt;. Often this is sporadic, and based on a specific requirement to hire in the short-to-medium term. In the meantime, we aim to let prospective candidates know the situation, although sometimes the volume of applications (particularly where they are wholly inappropriate “scatter gun”) means we can’t - apologies to anyone reading this who didn’t get a response. At this point we lose around 90-95% of candidates.&lt;/li&gt;
&lt;li&gt;This shortlist is then invited to a &lt;strong&gt;telephone interview&lt;/strong&gt;. This is generally a short (20-60 minute) phone call with the candidate, just to get an idea of their personality, to relate more information about the role on offer and to judge their expectations. This is often surprisingly light on technical or job-specific questions. At this point we probably lose around 20-50% of the remaining candidates.&lt;/li&gt;
&lt;li&gt;We then ask the remaining candidates to do a &lt;strong&gt;code sample&lt;/strong&gt;. This takes the form of a standard programming task (typically in Java), and we evaluate the candidate on the basis of their interpretation. We get quite a wide range of ability shown at this stage, but generally the standard is very high. Over the years we’ve come to take certain characteristics of this test as good pointers of a candidate’s way of thinking and level of ability. Even more interestingly, we provide absolutely no guidance on what we’re looking for to the candidate or (even more importantly), to the recruiter (if appropriate). Even with that lack of guidance, we find that successful candidates all tend to include the same things we’d expect, without us having to tell them. This gives us a feel for how candidates are able to code in a self-directed manner without the stress of the whiteboard-programming interview.&lt;/li&gt;
&lt;li&gt;We then ask the candidate in for a &lt;strong&gt;first round of interviews&lt;/strong&gt;. This typically lasts around two hours, with one or two interviewers in each hour-long slot. They typically focus on domain-specific problem solving (“How would you do X?”). For development that is generally algorithmic although may involve knowledge about specific hardware or software techniques. We also often ask very difficult questions on the edge of the candidate's area of expertise to see how they react to solving problems they’re not necessarily comfortable with. One thing we’re always careful to point out is that given the strength of the technical team here, for anything on your CV, chances are there will be an OpenGamma employee who’s at world-expert level in that thing. We always advise people to either exclude things they’re not comfortable with, or at least indicate their relative skill level (so that we don’t assume someone who has done a little bit of SQL can handle a technical interview with Kirk, who started his career doing nothing but database internals development).&lt;/li&gt;
&lt;li&gt;After the interviews, the head of department will ask each interviewer what they thought separately. Discussion between interviewers is discouraged before this point as it tends to introduce a sort of ‘group-think’ confirmation bias where people who privately would endorse a candidate would be influenced by other group members to change their mind.&lt;/li&gt;
&lt;li&gt;We then decide whether to bring the candidate in for a &lt;strong&gt;second round of interviews&lt;/strong&gt;. This typically includes another one to two hours of technical interviews and a final interview with someone senior such as myself. At this point Kirk always interviews every candidate to make sure people have time to ask questions about the business side of the equation, as well as to make sure that all developers will be a good fit. After all, we’re not just choosing candidates, they’re choosing us!&lt;/li&gt;
&lt;li&gt;At this point we decide whether to continue and extend an offer to the candidate or to pass.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In conclusion, I think the changes we have made over the lifetime of the company have improved the process of finding great people to join us at OpenGamma. It now takes us less time to find suitable candidates, puts less time pressure on candidates, and wastes less time of people who aren’t a good fit for us. Be under no illusions, we still have very high standards, and we’ve been told that we’re the hardest interviewing process in London at the moment. But if you think you can make the grade, and relish the opportunity to work with some of the top technologists in the UK, &lt;a href="http://www.opengamma.com/jobs"&gt;apply today&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We’ll be attending &lt;a href="http://siliconmilkroundabout.com/" target="_blank"&gt;Silicon Milkroundabout&lt;/a&gt; in London at the end of the month. It’s a great opportunity to meet a number of exciting start-ups, all in recruitment mode. If you are interested in learning more about working at OpenGamma, find us on stand 48.&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/yN8soI2OFHU" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/05/10/insight-into-the-opengamma-recruitment-process</guid>
<pubDate>2012-05-10T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/yN8soI2OFHU/insight-into-the-opengamma-recruitment-process</link><feedburner:origLink>http://www.opengamma.com/blog/2012/05/10/insight-into-the-opengamma-recruitment-process</feedburner:origLink></item>
<item>
<title>OpenGamma in a Minute - Animated</title>
<description>&lt;p&gt;Because OpenGamma's approach is quite different from a typical vendor in the financial technology space, we've sometimes found it challenging to get our philosophy across to the wider audience. If a picture is worth a thousand words, we thought a video must be even better - and decided to put together a quick animation explaining our approach to modern risk and trading analytics.&lt;/p&gt;
&lt;p&gt;So, without further ado, may I present:&lt;/p&gt;
&lt;iframe src="http://www.youtube.com/embed/REr-mvOL5Fg" width="560" height="315" frameborder="0" webkitAllowFullScreen="1" mozallowfullscreen="1" allowFullScreen="1"/&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/7aqqvXhqfB4" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/26/opengamma-in-a-minute-animated</guid>
<pubDate>2012-04-26T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/7aqqvXhqfB4/opengamma-in-a-minute-animated</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/26/opengamma-in-a-minute-animated</feedburner:origLink></item>
<item>
<title>OpenGamma OpenHouse - May 2012</title>
<description>&lt;p&gt;April has been a hectic month at the OpenGamma HQ thanks to our &lt;a href="http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-is-here"&gt;1.0 Platform release&lt;/a&gt;, but now that it's been released, we thought it's about time we organise another OpenGamma OpenHouse. We'll be opening our doors, serving up some food and drinks, and firing up the demo servers to showcase the new &lt;a href="http://www.opengamma.com/platform"&gt;OpenGamma Platform&lt;/a&gt; on &lt;strong&gt;Thursday, May 3rd, 2012.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that the 1.0 release is finally out, there’s lots of exciting stuff to demo. If you’d like to see our R module, the Excel integration, some of our other non-Open Source GUI tools, or the open source Bloomberg module in action, this is your chance to have a chat with the developers behind those features (and enjoy a few beers while you’re at it). Even better, we've got more stuff that isn't in 1.0, so you get a sneak peak at what's likely to be in 1.1 (and beyond!).&lt;/p&gt;
&lt;p&gt;Our &lt;a href="http://www.opengamma.com/blog/2010/11/02/opengamma-openhouse-17-november-2010"&gt;previous OpenHouse&lt;/a&gt; was in late 2010, so there have been a lot of changes in the company since then: we’ve moved offices and doubled the size of the team here in London. (So please don't show up at the old warehouse above the Kirkaldy Test Museum; we've moved to Park Street next to the Tate Modern).&lt;/p&gt;
&lt;p&gt;So come along to meet the team, see the Platform in action, and ask any questions you may have.&lt;/p&gt;
&lt;p&gt;You can just come by our offices in Southwark after work on Thursday, 3rd May, but we'd like you to &lt;a href="http://opengamma2012.eventbrite.com/"&gt;register on Eventbrite&lt;/a&gt; (Password: ValueAtRisk) so that we have a rough idea of who's coming, how much food to order, and, perhaps most importantly, how many beers to have ice cold!&lt;/p&gt;
&lt;p&gt;We hope to see as many of you from the London area as possible there! If you can't make it next week, we'll be organising another OpenHouse some time in June (&lt;a href="http://www.twitter.com/opengamma"&gt;follow us on Twitter&lt;/a&gt; to be among the first to hear about it).&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/2gYrOyheRlg" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/23/opengamma-openhouse-may-2012</guid>
<pubDate>2012-04-23T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/2gYrOyheRlg/opengamma-openhouse-may-2012</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/23/opengamma-openhouse-may-2012</feedburner:origLink></item>
<item>
<title>Countdown to R/Finance</title>
<description>&lt;p&gt;The fourth annual &lt;a href="http://www.rinfinance.com"&gt;R/Finance conference&lt;/a&gt; will take place in the Windy City next month. Aimed at users of R, the open source programming language for statistical computation and graphics, the event focuses on using R as a primary tool for financial risk management, analysis and trading.&lt;/p&gt;
&lt;p&gt;(To learn more about R and its exponential growth in the past few years, check out this excellent &lt;a href="http://www.revolutionanalytics.com/why-revolution-r/whitepapers/r-is-hot.php"&gt;white paper&lt;/a&gt; by Revolution Analytics.)&lt;/p&gt;
&lt;p&gt;Two members of the OpenGamma team attended last year’s conference, and talked about what early adopters of the &lt;a href="http://www.opengamma.com/platform"&gt;OpenGamma Platform&lt;/a&gt; wanted us to do with our &lt;a href="http://docs.opengamma.com/display/DOC/OpenGamma+Tools+for+R"&gt;R Integration Module&lt;/a&gt;. The response was so positive that we pushed forward on the implementation (now available as part of the &lt;a href="http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-released"&gt;1.0 release&lt;/a&gt;), and decided to join as one of the sponsors of the R/Finance conference. We’ll be showcasing the R integration on the first day of the conference. Additionally, Ana Nelson, a documentation consultant for OpenGamma, will be speaking on financial reporting and documentation using R and &lt;a href="http://www.dexy.it/"&gt;Dexy&lt;/a&gt; on the second day.&lt;/p&gt;
&lt;p&gt;Working with some of the foremost quants in the industry (like Andrew Rennie, the former global head of analytics at Merrill Lynch), we’ve learned that some of the advanced portfolio analytics required by modern quantitative trading strategies are ideally suited to the R programming environment. Using the OpenGamma R Integration Module analysts can create custom stresses and scenarios, using R’s rich ability to perform statistical perturbations on market data and security terms, all fully integrated with the rest of the &lt;a href="http://www.opengamma.com/platform"&gt;OpenGamma Platform&lt;/a&gt;. Even better, these calculations all happen on the same server-side infrastructure used by the rest of your installation: keeping your workstation free for the work that has to be done on it.&lt;/p&gt;
&lt;p&gt;We believe in supporting the tools that quantitative finance practitioners &lt;strong&gt;want&lt;/strong&gt; to use. That explains our deep commitment to Excel, now R, and forthcoming integrations such as Python and MATLAB. We don’t believe that you should have to use our GUIs to do your job.&lt;/p&gt;
&lt;p&gt;You’ll no doubt find many of us hanging out in the conference lobby and demoing the Platform - come and say hi.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/wKPwcTrxw_k" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/17/countdown-to-r-in-finance</guid>
<pubDate>2012-04-17T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/wKPwcTrxw_k/countdown-to-r-in-finance</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/17/countdown-to-r-in-finance</feedburner:origLink></item>
<item>
<title>Converting Javadocs from LaTeXlet to MathJax: A git-sed-vim Case Study</title>
<description>&lt;p&gt;Financial analytics are all about the math, and documenting financial analytics means making the math pretty, which on the internet can be an ugly thing to do. LaTeX has been the standard way to make math pretty in print since the 1980s, but making math pretty online has always been contentious and problematic.&lt;/p&gt;
&lt;p&gt;Projects like MathML have tried to help, but haven't really taken off because in order to display:&lt;/p&gt;
&lt;math&gt;
    &lt;mrow&gt;
        &lt;mi&gt;a&lt;/mi&gt;
        &lt;mo&gt;⁢&lt;!-- &amp;InvisibleTimes; --&gt;&lt;/mo&gt;
        &lt;msup&gt;
            &lt;mi&gt;x&lt;/mi&gt;
            &lt;mn&gt;2&lt;/mn&gt;
        &lt;/msup&gt;
        &lt;mo&gt;+&lt;/mo&gt;
        &lt;mi&gt;b&lt;/mi&gt;
        &lt;mo&gt;⁢&lt;!-- &amp;InvisibleTimes; --&gt;&lt;/mo&gt;
        &lt;mi&gt;x&lt;/mi&gt;
        &lt;mo&gt;+&lt;/mo&gt;
        &lt;mi&gt;c&lt;/mi&gt;
    &lt;/mrow&gt;
&lt;/math&gt;
&lt;p&gt;You need to type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="mathml-example.xml-pyg-1"/&gt;&lt;span class="nt"&gt;&amp;lt;math&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/1998/Math/MathML"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-2"/&gt;    &lt;span class="nt"&gt;&amp;lt;mrow&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-3"/&gt;        &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;a&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-4"/&gt;        &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;#x2062;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- &amp;amp;InvisibleTimes; --&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-5"/&gt;        &lt;span class="nt"&gt;&amp;lt;msup&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-6"/&gt;            &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;x&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-7"/&gt;            &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-8"/&gt;        &lt;span class="nt"&gt;&amp;lt;/msup&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-9"/&gt;        &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-10"/&gt;        &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;b&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-11"/&gt;        &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;#x2062;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- &amp;amp;InvisibleTimes; --&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-12"/&gt;        &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;x&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-13"/&gt;        &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-14"/&gt;        &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;c&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-15"/&gt;    &lt;span class="nt"&gt;&amp;lt;/mrow&amp;gt;&lt;/span&gt;
&lt;a name="mathml-example.xml-pyg-16"/&gt;&lt;span class="nt"&gt;&amp;lt;/math&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Example from &lt;a href="http://en.wikipedia.org/wiki/MathML"&gt;MathML wikipedia page&lt;/a&gt;. By contrast the LaTeX equivalent for this expression is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="polynomial-example.tex-pyg-1"/&gt;&lt;span class="s"&gt;$&lt;/span&gt;&lt;span class="nb"&gt;ax^&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;bx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;c&lt;/span&gt;&lt;span class="s"&gt;$&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Apart from the verbosity of the MathML markup, until very recently it wasn't safe to assume that most browsers would fully support HTML5, which includes MathML support.&lt;/p&gt;
&lt;p&gt;So, when OpenGamma began to look for a way to document the mathematics they were implementing, they looked for a LaTeX-based option and found it in &lt;a href="http://users.informatik.uni-halle.de/~grau/LaTeXlet/index.html"&gt;LaTeXlet&lt;/a&gt;, a custom &lt;a href="http://docs.oracle.com/javase/6/docs/technotes/guides/javadoc/taglet/overview.html"&gt;Taglet&lt;/a&gt; for javadocs. This taglet looks for specially formatted &lt;code&gt;@latex&lt;/code&gt; tags in Javadoc comments, renders them as LaTeX, and inserts the rendered math into the generated Javadocs as images.&lt;br/&gt;
The use of images is problematic for several reasons: they take extra time and processing power during the Javadoc build phase, latex must be installed on each machine that needs to generate Javadocs (this is not a trivial requirement), the generated images can be on the ugly side and, more importantly, they are very unaccessable. LaTeXlet further requires that you add an extra slash to each of the latex commands that you call. Here is an example of a Javadoc comment marked up for LaTeXlet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="latexlet-source-example.java-idio-2"/&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-3"/&gt;&lt;span class="cm"&gt; * Calculates the historical covariance of two return series. The covariance is given by:&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-4"/&gt;&lt;span class="cm"&gt; * {@latex.ilb %preamble{\\usepackage{amsmath}}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-5"/&gt;&lt;span class="cm"&gt; * \\begin{eqnarray*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-6"/&gt;&lt;span class="cm"&gt; * \\frac{1}{n(n-1)}\\sum\\limits_{i=1}^n (x_i - \\overline{x})(y_i - \\overline{y})&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-7"/&gt;&lt;span class="cm"&gt; * \\end{eqnarray*}}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-8"/&gt;&lt;span class="cm"&gt; * where {@latex.inline $x$} is the first return series, {@latex.inline $y$} is the&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-9"/&gt;&lt;span class="cm"&gt; * second return series and {@latex.inline $n$} is the number of data points.&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-10"/&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-11"/&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HistoricalCovarianceCalculator&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;CovarianceCalculator&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are a lot of tags in there. And while LaTeXlet will interpret "&lt;code&gt;\\frac&lt;/code&gt;" as "&lt;code&gt;\frac&lt;/code&gt;", any other LaTeX compiler will be unable to make sense of this. It's also a huge amount of extra typing to apply LaTeX-style formatting to the individual variables, i.e. &lt;code&gt;{@latex.inline $x$}&lt;/code&gt;. And because they are replaced by images, it renders the whole sentence unaccessible.&lt;/p&gt;
&lt;p&gt;While LaTeXlet had the advantage of being slightly less cumbersome than MathML, and allowed quants already familiar with LaTeX to use a tool they were proficient in, it was far from ideal, but was probably the best option available at the time. Now, happily, there is an alternative which isn't a least-bad option, and which is making it virtually painless to put beautiful math on the web. The &lt;a href="http://mathjax.com"&gt;MathJax&lt;/a&gt; javascript library allows you to insert plain old LaTeX in your HTML pages and it will render this LaTeX unobtrusively in a beautiful, accessible and standards-compliant way. Because you are writing standard LaTeX without any extra characters, you can also easily use this LaTeX in other PDF documentation, or paste it into tools like &lt;a href="http://mathb.in"&gt;mathb.in&lt;/a&gt; to get a quick preview.&lt;/p&gt;
&lt;p&gt;Cleaning up the documentation was one of the goals for the &lt;a href="http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-released"&gt;1.0 release of the OpenGamma Platform&lt;/a&gt;. After we verified that we could apply MathJax to our generated Javadocs, I then had to solve the problem of converting almost 200 existing files with LaTeXlet-style markup into the simpler format we would use going forward. I wanted to find a way to automate the process, not only for the obvious drudgery it would otherwise involve, but because the probability of making mistakes in manually editing such content was very high.&lt;/p&gt;
&lt;p&gt;I started working on a &lt;a href="http://www.gnu.org/software/sed/"&gt;sed&lt;/a&gt; script which would convert the double slashes to single slashes, get rid of the unnecessary &lt;code&gt;@latex&lt;/code&gt; tags and their associated brackets and replace them with math mode declarations like &lt;code&gt;$$&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
s/\s*%preamble{.*}}//g
s/{@latex.inline \(\$[^$]*\$\)}/\1/g
s/{@latex.ilb/$$/
s/end{eqnarray\*}[\s\*]*}\s*/end{eqnarray*}\n * $$/
s/end{align\*}[\s\*]*}\s*/end{align*}\n * $$/
s/\\\(\\\w\)/\1/g
&lt;/pre&gt;
&lt;p&gt;This will give output like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="latexlet-source-example.java-used-idio-2"/&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-3"/&gt;&lt;span class="cm"&gt; * Calculates the historical covariance of two return series. The covariance is given by:&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-4"/&gt;&lt;span class="cm"&gt; * $$&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-5"/&gt;&lt;span class="cm"&gt; * \begin{eqnarray*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-6"/&gt;&lt;span class="cm"&gt; * \frac{1}{n(n-1)}\sum\limits_{i=1}^n (x_i - \overline{x})(y_i - \overline{y})&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-7"/&gt;&lt;span class="cm"&gt; * \end{eqnarray*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-8"/&gt;&lt;span class="cm"&gt; * $$&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-9"/&gt;&lt;span class="cm"&gt; * where $x$ is the first return series, $y$ is the&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-10"/&gt;&lt;span class="cm"&gt; * second return series and $n$ is the number of data points.&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-11"/&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-12"/&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HistoricalCovarianceCalculator&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;CovarianceCalculator&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I developed this script by first committing all my other changes so I was starting with a clean git repository, and then iterating the sed script by running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="apply-sed.sh-pyg-1"/&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /mnt/work/OG-Platform/projects/
&lt;a name="apply-sed.sh-pyg-2"/&gt;git checkout HEAD .
&lt;a name="apply-sed.sh-pyg-3"/&gt;find . -name &lt;span class="s2"&gt;"*.java"&lt;/span&gt; -exec sed -f /mnt/work/blog/remove-latexlet.sed -i &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;a name="apply-sed.sh-pyg-4"/&gt;git diff . | less
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I would review the diff and then modify the sed script to improve its recognition. I repeated this several times until I was happy enough. This script isn't perfect, it sometimes misses the closing &lt;code&gt;}&lt;/code&gt; of the &lt;code&gt;@latex.il&lt;/code&gt; environments, and it also was a little overzealous in converting all instances of &lt;code&gt;\\&lt;/code&gt; to &lt;code&gt;\&lt;/code&gt; rather than just those in math mode chunks.&lt;/p&gt;
&lt;p&gt;Here's another Javadoc source example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="latexlet-source-example.java-idio-14"/&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-15"/&gt;&lt;span class="cm"&gt; * A simple chooser option gives the holder the right to choose whether the&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-16"/&gt;&lt;span class="cm"&gt; * option is to be a standard call or put (both with the same expiry) after a&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-17"/&gt;&lt;span class="cm"&gt; * certain time. The exercise style of the option, once the choice has been&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-18"/&gt;&lt;span class="cm"&gt; * made, is European.&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-19"/&gt;&lt;span class="cm"&gt; * &amp;lt;p&amp;gt;&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-20"/&gt;&lt;span class="cm"&gt; * The payoff of this option is:&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-21"/&gt;&lt;span class="cm"&gt; * {@latex.ilb %preamble{\\usepackage{amsmath}}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-22"/&gt;&lt;span class="cm"&gt; * \\begin{align*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-23"/&gt;&lt;span class="cm"&gt; * \\mathrm{payoff} = \\max(c_{BSM}(S, K, T_2), p_{BSM}(S, K, T_2))&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-24"/&gt;&lt;span class="cm"&gt; * \\end{align*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-25"/&gt;&lt;span class="cm"&gt; * }&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-26"/&gt;&lt;span class="cm"&gt; * where {@latex.inline $c_{BSM}$} is the general Black-Scholes Merton call&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-27"/&gt;&lt;span class="cm"&gt; * price, {@latex.inline $c_{BSM}$} is the general Black-Scholes Merton put&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-28"/&gt;&lt;span class="cm"&gt; * price (see {@link BlackScholesMertonModel}), {@latex.inline $K$} is the&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-29"/&gt;&lt;span class="cm"&gt; * strike, {@latex.inline $S$} is the spot and {@latex.inline $T_2$}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-30"/&gt;&lt;span class="cm"&gt; * is the time to expiry of the underlying option.&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-31"/&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;a name="latexlet-source-example.java-idio-32"/&gt;
&lt;a name="latexlet-source-example.java-idio-33"/&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleChooserOptionDefinition&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;OptionDefinition&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here it is after running 'sed', you can see it misses the closing } on the line after &lt;code&gt;\end{align*}&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;a name="latexlet-source-example.java-used-idio-15"/&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-16"/&gt;&lt;span class="cm"&gt; * A simple chooser option gives the holder the right to choose whether the&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-17"/&gt;&lt;span class="cm"&gt; * option is to be a standard call or put (both with the same expiry) after a&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-18"/&gt;&lt;span class="cm"&gt; * certain time. The exercise style of the option, once the choice has been&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-19"/&gt;&lt;span class="cm"&gt; * made, is European.&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-20"/&gt;&lt;span class="cm"&gt; * &amp;lt;p&amp;gt;&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-21"/&gt;&lt;span class="cm"&gt; * The payoff of this option is:&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-22"/&gt;&lt;span class="cm"&gt; * $$&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-23"/&gt;&lt;span class="cm"&gt; * \begin{align*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-24"/&gt;&lt;span class="cm"&gt; * \mathrm{payoff} = \max(c_{BSM}(S, K, T_2), p_{BSM}(S, K, T_2))&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-25"/&gt;&lt;span class="cm"&gt; * \end{align*}&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-26"/&gt;&lt;span class="cm"&gt; * }&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-27"/&gt;&lt;span class="cm"&gt; * where $c_{BSM}$ is the general Black-Scholes Merton call&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-28"/&gt;&lt;span class="cm"&gt; * price, $c_{BSM}$ is the general Black-Scholes Merton put&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-29"/&gt;&lt;span class="cm"&gt; * price (see {@link BlackScholesMertonModel}), $K$ is the&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-30"/&gt;&lt;span class="cm"&gt; * strike, $S$ is the spot and $T_2$&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-31"/&gt;&lt;span class="cm"&gt; * is the time to expiry of the underlying option.&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-32"/&gt;&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;a name="latexlet-source-example.java-used-idio-33"/&gt;
&lt;a name="latexlet-source-example.java-used-idio-34"/&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleChooserOptionDefinition&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;OptionDefinition&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, I knew I wanted to manually check each file before committing the changes anyway, so I would be able to fix these issues and tidy up any other little niggles that I spotted. It wasn't worth spending more time on the .sed script, instead I needed to find out how I was going to identify all of the changed files and make sure I checked each of them.&lt;/p&gt;
&lt;p&gt;I use vim as my text editor. I hoped that a solution might be found using some sort of plugin for vim which would let me systematically work through the list of modified files generated by running "git status". Happily, I found exactly such a tool in &lt;a href="https://github.com/tpope/vim-fugitive"&gt;fugitive.vim&lt;/a&gt;. After I installed it using pathogen.vim (by the same author), and watched the &lt;a href="http://vimcasts.org/episodes/fugitive-vim---a-complement-to-command-line-git/"&gt;first&lt;/a&gt; and &lt;a href="http://vimcasts.org/episodes/fugitive-vim-working-with-the-git-index/"&gt;second&lt;/a&gt; vimcasts about fugitive, I quickly had a very efficient workflow going.&lt;/p&gt;
&lt;p&gt;I would run &lt;code&gt;:Gstatus&lt;/code&gt; to open a new buffer listing all the modified files in the repository - which were the files that had been changed by running the final version of the sed script. I type return while over the first file in the "Changes not staged for commit:" list, which would open that file for editing. Then I would run &lt;code&gt;:Gdiff&lt;/code&gt; on that file which showed me the current changes using vimdiff. Then I could tweak the Javadoc in the working copy, fixing anything that the sed script missed and making any other small edits. When I was finished I would save my changes, return to the status window and type a -, which would add the file I had just been editing to the "Changes to be committed:" list. At this point the file would disappear from the "Changes not staged.." list and the cursor would already be positioned over the next file, so I just had to type return to start editing it, and the process begins again. Here's a picture of what it looked like:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/using-fugitive.fullsize.prelude_version_2.png" rel="lightbox"&gt;&lt;img class="boxed" src="http://og-web-www.s3.amazonaws.com/using-fugitive.prelude_version_3.png" alt="Screenshot of using fugitive.vim plugin" width="500" height="309"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With this approach it was very fast and straightforward for me to work my way through the list of modified files, and I could be confident that I had checked every file before adding it to the list for the next commit. I could also exit vim at any time and easily pick up where I left off later by issuing another :Gstatus command. I did this a few times to make sure that I didn't have any files lurking with unsaved changes, and to generate the Javadocs from outside of vim.&lt;/p&gt;
&lt;p&gt;The result is a much cleaner javadoc build, several dependencies removed from the Ivy repository and Ant configuration files, happier developers who can much more easily update and input mathematical descriptions, and beautifully rendered LaTeX that can be re-used in multiple contexts, both for print and web.&lt;/p&gt;
&lt;p&gt;Mathematical equations show up in the OpenGamma codebase to describe statistical distributions like the &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/math/statistics/distribution/GeneralizedParetoDistribution.html"&gt;Generalized Pareto Distribution&lt;/a&gt;, functions such as those used to &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/math/curve/AddCurveSpreadFunction.html"&gt;add&lt;/a&gt;, &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/math/curve/SubtractCurveSpreadFunction.html"&gt;subtract&lt;/a&gt;, &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/math/curve/MultiplyCurveSpreadFunction.html"&gt;multiply&lt;/a&gt; and &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/math/curve/DivideCurveSpreadFunction.html"&gt;divide&lt;/a&gt; curves, calculators like the &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/financial/riskreward/JensenAlphaCalculator.html"&gt;JensenAlphaCalculator&lt;/a&gt; and &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/financial/riskreward/SharpeRatioCalculator.html"&gt;SharpeRatioCalculator&lt;/a&gt;, and of course models such as the &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/financial/model/option/pricing/analytic/BlackScholesMertonModel.html"&gt;BlackScholesMertonModel&lt;/a&gt; and the &lt;a href="http://docs-static.opengamma.com/1.0.0/java/javadocs/com/opengamma/analytics/financial/model/option/pricing/analytic/BjerksundStenslandModel.html"&gt;BjerksundStenslandModel&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/Be4MZ4L6yZc" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/12/converting-javadocs-from-latexlet-to-mathjax</guid>
<pubDate>2012-04-12T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/Be4MZ4L6yZc/converting-javadocs-from-latexlet-to-mathjax</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/12/converting-javadocs-from-latexlet-to-mathjax</feedburner:origLink></item>
<item>
<title>Conventions, Bloody Conventions!</title>
<description>&lt;p&gt;In our experience, as Quantitative Analysts, Risk Managers, Back-Office Officers or Traders, we've all one day or another tried to look up a small detail about a very familiar instrument without finding it. Does Euribor use the end-of-month rule? What is the standard payment frequency for a three-year AUD swap? What is the last trading date of a mid-curve option on Liffe? Those questions may sound familiar. Often, the only way to find answers is to ask your colleagues, search the internet or call a counterpart. Everybody is supposed to know about them, but, to the best of my knowledge, and to my longstanding despair, they are not available in one unique, easily accessible place.&lt;/p&gt;
&lt;p&gt;After ten years of looking for those details, trying to remember them only to forget them the next week and look for them again, I decided not to trust my memory anymore and to write them down. The writing did not happen overnight, not even in a fortnight. The details were collected over almost one year while we were implementing the different instruments in our libraries and creating test portfolios.&lt;/p&gt;
&lt;p&gt;Now that I have them in writing, when a colleague or a friend asks me for those details, I just have to find the right section and copy and paste it.&lt;/p&gt;
&lt;h3&gt;Introducing the Interest Rate Instruments and Market Conventions Guide&lt;/h3&gt;
&lt;p&gt;At OpenGamma, we have decided to go one step further: shape this information in the form of a booklet and make it available to everyone in the industry. Being an Open Source company, we have the tradition to distribute widely what we do when we believe it could be useful for others.&lt;/p&gt;
&lt;p&gt;Nowhere in the document do I describe pricing or valuation mechanisms, even for the simplest instruments. The link to valuation is that any valuation technique for any instrument presented should include all the relevant instrument features. Most of the standard books and articles smooth the roughness of real life. Settlement lags are nowhere to be seen; day counts and business day conventions are supposed to appear magically, when they are mentioned at all. We all know that nothing appears magically and that there is no such thing as a free lunch. I do not offer you any of those free lunches, but hopefully the document can help you find the salt and pepper to season your own lunch.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The goal of the document is to present conventions and market standards for the most common interest rate instruments.&lt;/strong&gt; I have done my best to collect the information and check it. Obviously the document is not perfect and we plan to add, complement, or correct it when necessary. Do not hesitate to suggest corrections and additions.&lt;/p&gt;
&lt;p&gt;The market standards are relative, and they evolve. For the same instrument, two groups of people may use different conventions. This is the case with USD swaps: some use an annual money market basis on the fixed leg, and others semi-annual bond basis. The standards evolve; this is the case with swaptions for which the standard changed from an up-front premium to a forward premium in September 2010.&lt;/p&gt;
&lt;p&gt;The document is certainly not intended to be read from start to end like fiction. If quantitative finance is to be compared to a novel, this booklet would be the introduction of the main characters. It is a reference document and I expect users to read at most one chapter at a time, and more often one section or even one single line. This is also the way it was written, adding lines, currencies, and instruments when they were required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You can &lt;a onclick="javascript: pageTracker._trackPageview('/downloads/interest-rate-instruments-and-market-conventions-guide.pdf');" href="http://www.opengamma.com/downloads/interest-rate-instruments-and-market-conventions-guide.pdf"&gt;download the booklet here&lt;/a&gt;.&lt;/strong&gt; It is published under a Creative Commons license (CC BY 3.0), so you are free to use it in any form and redistribute it. However, we do ask that you indicate that the source is the &lt;strong&gt;OpenGamma Interest Rate Instruments and Market Conventions Guide&lt;/strong&gt;. If you want to pass it to someone, we'd suggest that you point to the original document so one always has the latest version (and the credit is given where due). The current version is named 1.0, just like the version of the &lt;a href="http://www.opengamma.com/platform"&gt;OpenGamma Platform&lt;/a&gt; just released on 2nd April.&lt;/p&gt;
&lt;p&gt;The conventions described in this booklet are naturally already implemented in the OpenGamma Platform and our &lt;a href="http://docs.opengamma.com/display/DOC/Analytics"&gt;Analytics Library&lt;/a&gt;. If you haven't already adopted it, we highly recommend &lt;a href="http://developers.opengamma.com/downloads/platform-1.0.0"&gt;downloading&lt;/a&gt; the fresh new Platform available since Monday!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The devil is in the details.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/ywGJ5S39ahA" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/05/interest-rate-instruments-and-market-conventions-guide</guid>
<pubDate>2012-04-05T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/ywGJ5S39ahA/interest-rate-instruments-and-market-conventions-guide</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/05/interest-rate-instruments-and-market-conventions-guide</feedburner:origLink></item>
<item>
<title>OpenGamma Platform 1.0 Is Here - Pop the Champagne!</title>
<description>&lt;p&gt;Today OpenGamma has released version 1.0 of our flagship technology stack, the &lt;a href="http://www.opengamma.com/platform"&gt;OpenGamma Platform&lt;/a&gt;. While Jim, our Head of Platform Development, has &lt;a href="http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-released"&gt;details on the technical side&lt;/a&gt;, I wanted to talk about where this takes us as a company and ecosystem.&lt;/p&gt;
&lt;p&gt;When we set out on the OpenGamma journey, our mission was simple: to make the same standard of tools available to the most sophisticated market participants available to everyone. In a world filled with black boxes, we wanted to bring radical transparency. In a market where way too many firms keep rebuilding the same systems, we wanted to allow developers to focus on what’s proprietary about &lt;em&gt;their&lt;/em&gt; firms.&lt;/p&gt;
&lt;p&gt;It's taken us 2.5 years, over 25 developer years, 11,000 test cases and 750,000 lines of code to get here: &lt;strong&gt;the world's first production-grade Open Source system for trading and risk analytics and data management.&lt;/strong&gt; From a modern, modular analytics and pricing library, to a near-real-time streaming calculation engine, to data management, to client tools, we know that the OpenGamma Platform contains everything you need as the basis for custom installations.&lt;/p&gt;
&lt;h2&gt;What took us so long?&lt;/h2&gt;
&lt;p&gt;We released 0.9 when we thought that the code was feature-rich enough that it showed what we were capable of, and was an excellent starting point for evaluation efforts. We also said that we needed to wait to officially call something as 1.0 until we were confident that the system would support your use 24/7/365.&lt;/p&gt;
&lt;p&gt;Since then we’ve had thousands of downloads by people evaluating and using the system, providing us with extensive feedback. We're also in use in anger every day by some of the largest and most sophisticated hedge funds in the world.&lt;/p&gt;
&lt;p&gt;How do we know we’re ready? &lt;em&gt;They told us we’re ready.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;1.0 is battle tested and ready for use in production today.&lt;/p&gt;
&lt;h2&gt;What's next?&lt;/h2&gt;
&lt;p&gt;Unlike other vendors, we're not shy about telling you what we're working on. We've got our &lt;a href="http://jira.opengamma.com/browse/PLAT#selectedTab=com.atlassian.jira.plugin.system.project%3Aroadmap-panel"&gt;roadmap&lt;/a&gt; on our website so that you know where we’re going and roughly when we'll get there.&lt;/p&gt;
&lt;p&gt;However, our roadmap can really be summed up in a few key points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;While we already have &lt;a href="http://www.opengamma.com/platform/features/asset-class-coverage.pdf"&gt;extensive asset class coverage&lt;/a&gt; (&lt;a href="http://www.opengamma.com/platform/features/asset-class-coverage.pdf"&gt;PDF summary&lt;/a&gt; / &lt;a href="http://docs.opengamma.com/display/DOC/Top+Level+Value+Requirements"&gt;full analytics documentation&lt;/a&gt;), we're going to improve it. You've told us that while you can already incorporate 3rd party models easily, you don’t want to have to do it (or go to a traditional black-box analytics library vendor).&lt;/li&gt;
&lt;li&gt;While many of you are already comfortable and familiar with building your own end-user tools, you want us to do more out of the box. So we'll be enhancing the end-user tools available to both Open Source users and commercial customers and continue to push our already industry-leading integrations with systems like Excel and R.&lt;/li&gt;
&lt;li&gt;While we already have a pretty impressive set of data integrations, we want to make sure you can download the system and have live risk on your portfolios using your existing data as fast as possible. Unlike legacy vendors, we don't make money by dragging on installations as long as possible to sell consulting services: we want you up, running, and in production as fast as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But more than just categories of features, our roadmap is simple: &lt;strong&gt;Do whatever it takes to make our customers successful.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Whether you're a developer at a hedge fund, an academic quant at a university, or a risk manager at a bank, we want to hear from you. &lt;a href="http://developers.opengamma.com/downloads/platform-1.0.0"&gt;Download the code&lt;/a&gt;, &lt;a href="http://docs.opengamma.com/"&gt;read the docs&lt;/a&gt;, or &lt;a href="http://www.opengamma.com/platform/request-demo"&gt;contact us for a conversation and demonstration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you're tired of building and maintaining way more code than you need to, or tired of the way legacy vendors have been treating you, you’ve found the right people.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/YgRPWU1rzXQ" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-is-here</guid>
<pubDate>2012-04-02T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/YgRPWU1rzXQ/opengamma-platform-1.0-is-here</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-is-here</feedburner:origLink></item>
<item>
<title>OpenGamma Platform 1.0 Released</title>
<description>&lt;p&gt;The 1.0 version of the OpenGamma Platform is finally out. It’s been in the making for longer than anticipated, but we believe it was essential to wait until we have all the main components ready to ship.&lt;/p&gt;
&lt;p&gt;In this blog post, I’ll briefly go over the most significant changes. If you can’t wait to see it for yourself, head over to our developers’ site to &lt;a href="http://developers.opengamma.com/downloads/platform-1.0.0"&gt;download the Platform&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Bloomberg Integration&lt;/h2&gt;
&lt;p&gt;After &lt;a href="http://www.opengamma.com/blog/2012/02/02/bloomberg-market-data-api-opengamma-1.0-release"&gt;Bloomberg’s recent announcement to open source its API&lt;/a&gt;, we’ve been able to include the Bloomberg module in our 1.0 release. This will allow you to load automatic reference data for exchange-traded securities, as well as load and update time series. Our integration module also now Open Sources our &lt;a href="http://docs.opengamma.com/display/DOC/Major+Components+and+Subsystems#MajorComponentsandSubsystems-ogld"&gt;OpenGamma Live Data Adapter&lt;/a&gt; for pulling real-time streaming data into your OpenGamma environment from your Terminal, SAPI, or Managed B-Pipe instance. You can now download the Platform, hook it up to your existing Bloomberg infrastructure, and be doing live trading and risk analytics with real world data in a matter of minutes!&lt;/p&gt;
&lt;p&gt;This means that when evaluating, you have two basic options. You can choose the classic “Examples” package, which works with entirely mock data, just as in 0.9. However, if you have access to a Bloomberg Terminal, SAPI, or Managed B-PIPE instance, you can use the “BloombergExamples” package to work with real data and get your own portfolios up and running in the system in a matter of minutes.&lt;/p&gt;
&lt;h2&gt;&lt;a href="http://docs.opengamma.com/display/DOC/OpenGamma+Web+Interface"&gt;New HTML5 Web GUI&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Our HTML5 Web GUI continues to improve. While we’re busy rewriting our Web Analytics Viewer from scratch (to make it easier to include in your custom portals and applications), there have been a number of improvements to the main Open Source Platform GUI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Web Analytics Viewer now supports Market Data Snapshots as well as different Live Data configurations as data sources and fallback to Historical Time Series for market data;&lt;/li&gt;
&lt;li&gt;It also supports dynamic re-aggregation of your portfolio on the fly - without reconfiguring your View Definition;&lt;/li&gt;
&lt;li&gt;Many of our Data Master viewers (like Portfolios, Positions, and Securities) are far better integrated, and can pull in key historical time series directly into the viewer for Securities to make it quicker to do common tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, our whole GUI has been retrofitted with our new “Push REST” capabilities to notify all clients of data changes whenever they happen anywhere in your environment: reloading to get changes other people on a desk have made is a thing of the past.&lt;/p&gt;
&lt;h2&gt;&lt;a href="http://docs.opengamma.com/display/DOC/Sources%2C+Masters%2C+and+Databases"&gt;Database Masters&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We continue to improve our Database Masters. Aside from numerous performance improvements throughout (particularly our Historical Time Series database schema and Master code), we’ve completely rewritten our Batch Risk database and masters to allow far more types of data to be stored and queried with the most complex of View Definitions.&lt;/p&gt;
&lt;p&gt;Our data masters have also been enhanced to allow runtime tagging of Securities, Trades, Positions, and Portfolios. This allows you to put in any custom attributes required on any of these data types, and incorporate that with other new elements like our expression language for dynamic portfolio filtering and aggregation exactly as the “native” data fields.&lt;/p&gt;
&lt;h2&gt;&lt;a href="http://docs.opengamma.com/display/DOC/Analytics"&gt;Asset Classes and Analytics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The OpenGamma Platform continues to extend its support for new asset classes and analytical methods.&lt;/p&gt;
&lt;p&gt;Perhaps the most important change since 0.9.0 has been the amount of time that our Quantitative Development team has spent on making sure that we have a single source of all major market conventions for the G8 (and nearly the whole of the G20). Not only have we incorporated this into the Platform so that we have accurate cashflow determinations for assets in these currencies, but we have a booklet (forthcoming) that has all this information in one place as a guide you can use for your own development.&lt;/p&gt;
&lt;p&gt;Notable new assets include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Caps/Floors (including CMS)&lt;/li&gt;
&lt;li&gt;Inflation products&lt;/li&gt;
&lt;li&gt;Additional types of IR Swaps&lt;/li&gt;
&lt;li&gt;OIS&lt;/li&gt;
&lt;li&gt;Equity Variance Swaps&lt;/li&gt;
&lt;li&gt;FX Futures&lt;/li&gt;
&lt;li&gt;Digital FX Options&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://www.opengamma.com/platform/features/asset-class-coverage.pdf"&gt;View the full list of asset classes currently covered&lt;/a&gt; (PDF)&lt;/p&gt;
&lt;p&gt;We’ve also extended the types of analytical methods available, in particular enhancing the number of different analytical methods available for IR Swaptions and applying our Local Volatility and SVI models to multiple asset classes.&lt;/p&gt;
&lt;p&gt;But no matter how good our analytics library or data management may be, there will always be times when you won’t want to use it, but have a system that can generate sensitivities you want to aggregate with the rest of your portfolio (common examples are credit derivatives, ABS, and RMBS). To handle that, we now have &lt;strong&gt;full support for External Sensitivities&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You can now create an External Sensitivities Security, assign the appropriate risk factors to it, and use the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Yield curve sensitivity mapping&lt;/li&gt;
&lt;li&gt;Separate yield curve/credit/all sensitivities buckets&lt;/li&gt;
&lt;li&gt;DV01, CS01, Historical VaR&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;h2&gt;&lt;a href="http://docs.opengamma.com/display/DOC/OpenGamma+Tools+for+R"&gt;R Integration Module&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We’ve found a large number of quants and risk managers using the R statistical programming environment to drive deep and custom statistical analysis of their portfolios. In keeping with our dedication to supporting the tools that end-users actually want to use, we have taken our industry-leading Excel Integration Module, stripped away the parts that aren’t Excel specific, created the OpenGamma Language Integration package, and used that to provide the same level of extremely deep, useful integration with the R statistical programming environment.&lt;/p&gt;
&lt;p&gt;Everything that you would expect by now from a tight OpenGamma integration is there: you can pull in all types of data available in your OpenGamma Platform instance, and they all appear as native R objects; you can drive shocks and stress tests and historical simulations, including perturbing market data at either the individual ticker or tensor level. You can even create custom trades and portfolios from R to do what-if scenarios.&lt;/p&gt;
&lt;p&gt;We think this is extremely powerful, and we’re thrilled that this is in the Open Source OpenGamma Platform! (also, we’re a sponsor of the &lt;a href="http://www.rinfinance.com/"&gt;R/Finance Conference&lt;/a&gt; in Chicago in May; if you’re in the area come on by and say hi!).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;04/04/2012 Update: The R Installer is now available on the &lt;a href="http://developers.opengamma.com/downloads/platform-1.0.0"&gt;downloads&lt;/a&gt; page.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;Other Updates&lt;/h2&gt;
&lt;p&gt;Perhaps the most immediate change developers will notice is the &lt;strong&gt;improved build system&lt;/strong&gt; – it’s actually now a single-step process. We’re confident that you’ll find deployment a whole lot easier. We’ve also included better ant target names.&lt;/p&gt;
&lt;p&gt;For those of you evaluating the platform independently, we’ve included &lt;strong&gt;sample data&lt;/strong&gt; for new asset classes, and &lt;strong&gt;improved data import/export&lt;/strong&gt;: there is a standard import format for security/portfolio data, as well as a framework for custom importers.&lt;/p&gt;
&lt;p&gt;Finally, we’ve completely &lt;strong&gt;overhauled the configuration system&lt;/strong&gt;. You’ll find that deployment and maintenance have been made significantly user-friendlier, using the distributed component management system.&lt;/p&gt;
&lt;p&gt;As ever, we welcome your feedback; please add your comment below. For any technical questions, we recommend contacting our technical team through our &lt;a href="http://forums.opengamma.com/forum/"&gt;forums&lt;/a&gt;. A special thank you to those of you already evaluating the Platform who have posted questions, comments and suggestions on the forums over the past months.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://developers.opengamma.com/downloads/platform-1.0.0"&gt;&lt;strong&gt;Download OpenGamma Platform 1.0&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.opengamma.com/platform/request-demo"&gt;Request a demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://docs.opengamma.com/display/DOC/OpenGamma+Platform+Documentation"&gt;Browse documentation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/vVmeVd0D6LQ" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-released</guid>
<pubDate>2012-04-02T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/vVmeVd0D6LQ/opengamma-platform-1.0-released</link><feedburner:origLink>http://www.opengamma.com/blog/2012/04/02/opengamma-platform-1.0-released</feedburner:origLink></item>
<item>
<title>Partial Application in JavaScript Revisited</title>
<description>&lt;p&gt;A few years ago, &lt;a href="http://ejohn.org/blog/partial-functions-in-javascript/"&gt;John Resig wrote a blog post about partial application in JavaScript&lt;/a&gt; and proposed extending the &lt;code&gt;Function&lt;/code&gt; prototype with a new method: &lt;code&gt;partial&lt;/code&gt;. This technique is quite powerful, as it allows for much more concise and expressive code. We use partial application extensively in our UI codebase, particularly in our &lt;a href="https://github.com/OpenGamma/OG-Platform/blob/master/projects/OG-Web/web-engine/prototype/scripts/og/api/og.api.rest.js"&gt;wrapper for OpenGamma's REST API&lt;/a&gt;, where it has saved us several hundred lines of code. Fewer lines of code often means &lt;a href="http://www.paulgraham.com/power.html"&gt;fewer bugs&lt;/a&gt;. And this particular technique cuts down on repeated code and copy/paste errors.&lt;/p&gt;
&lt;p&gt;The technique takes advantage of the functional nature of JavaScript (treating functions as first-class objects) and allows information to be encapsulated inside a function. It returns a function with some of its arguments pre-populated. It uses JavaScript's prototypal inheritance to extend all instances of functions:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/2030044.js"&gt;
//
// 
    
// 
//
&lt;/script&gt;
&lt;p&gt;The problem with this is that the &lt;code&gt;args&lt;/code&gt; array gets cached. Here is the example use case from the original blog post:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/2030122.js"&gt;
//
// 
    
// 
//
&lt;/script&gt;
&lt;p&gt;But suppose that function is used again. The results are unexpected:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/2030201.js"&gt;
//
// 
    
// 
//
&lt;/script&gt;
&lt;p&gt;What's happened is that the first function has been cached inside the &lt;code&gt;args&lt;/code&gt; array and all subsequent calls to &lt;code&gt;delay&lt;/code&gt; are being pre-populated with that first function. Additionally, JavaScript &lt;code&gt;Function&lt;/code&gt; instances can have arbitrary properties attached to them, but this particular implementation of &lt;code&gt;Function.prototype.partial&lt;/code&gt; will lose the references to any additional properties that may have been added to a &lt;code&gt;Function&lt;/code&gt; instance. Even though extending &lt;code&gt;Function&lt;/code&gt; instances with custom properties is fairly uncommon, it is nonetheless a feature of the language that &lt;code&gt;partial&lt;/code&gt; should retain. If a function is being pre-populated, the resultant function should contain references to all the original function's properties. So, with those two concerns in mind, here's our implementation of partial application:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/2006867.js"&gt;
//
// 
    
// 
//
&lt;/script&gt;
&lt;p&gt;If we run the same test case, we get better results this time:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/2030387.js"&gt;
//
// 
    
// 
//
&lt;/script&gt;
&lt;p&gt;Extending native objects in JavaScript is a controversial subject. The biggest philosophical difference between libraries like &lt;a href="http://jquery.org/"&gt;jQuery&lt;/a&gt; and &lt;a href="http://prototypejs.org/"&gt;Prototype&lt;/a&gt; is that jQuery does &lt;em&gt;not&lt;/em&gt; extend native objects. We did not choose to extend the &lt;code&gt;Function&lt;/code&gt; prototype lightly; there are a very small number of cases where we have elected to extend native objects. But in this particular case, the gains in expressiveness and the ability to write less (and more concise) code are compelling.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/xVsWIxyPfeI" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/03/22/partial-application-in-javascript-revisited</guid>
<pubDate>2012-03-22T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/xVsWIxyPfeI/partial-application-in-javascript-revisited</link><feedburner:origLink>http://www.opengamma.com/blog/2012/03/22/partial-application-in-javascript-revisited</feedburner:origLink></item>
<item>
<title>Managing a Large Mixed Public/Private Java Project Using Git</title>
<description>&lt;p&gt;Having a mix of public and private source code repositories poses an interesting challenge to any organisation. How do you achieve the necessary combination of openness (which is assumed by Git at an architectural level), and the necessary level of confidentiality for clients and commercial components?&lt;/p&gt;
&lt;p&gt;In this post, I wanted to shed some light on how we’ve managed to address that challenge and come up with something that works pretty well for us at OpenGamma.&lt;/p&gt;
&lt;h3&gt;Why we chose Git in the first place&lt;/h3&gt;
&lt;p&gt;When we first started OpenGamma, the version control system that I was most comfortable with was &lt;a href="http://www.perforce.com/"&gt;Perforce&lt;/a&gt;. While Perforce is a great system, it didn’t really seem appropriate for an Open Source project. Although the &lt;a href="http://www.perforce.com/product/components/perforce_visual_client"&gt;Perforce client software&lt;/a&gt; is free to download, we felt that the Open Source community in general frowned upon using proprietary software for version control. We did consider Subversion, but given that the world seemed to be moving to distributed version control, we decided to take the plunge with Git. We immediately decided to use &lt;a href="https://github.com/opengamma"&gt;GitHub&lt;/a&gt; as a host for our repositories as part of our general approach of using hosted services where possible.&lt;a href="http://github.com"&gt;&lt;img class="floatright" src="http://og-web-www.s3.amazonaws.com/Octocat-logo.prelude_version_2.png" alt="GitHub" width="150" height="150"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While OpenGamma is primarily an &lt;a href="http://www.opengamma.com/platform/radically-open"&gt;Open Source platform&lt;/a&gt;, we do have some proprietary components only available to commercial customers. In addition, our support methodology allows us to share code directly with customers to provide hands-on, proactive support. Unfortunately Git is really not designed to support a mixed public/private model. What we really want is to be able to wall off access to certain parts of a repository, but when you think about it more deeply, it’s actually pretty understandable why Git doesn’t let you do this. For example, if you commit across public and private code, is it acceptable to even expose the file names of the private files? Probably not. What about history? What if something is moved from private to public or vice versa? Do you want all these cross-linking chains of commits? Probably not.&lt;/p&gt;
&lt;p&gt;Because OpenGamma is a heavily componentized system, we’ve always operated on a quite fine-grained project basis, and have formed a moderately complex tree of dependencies between modules (primarily managed by Eclipse and Ivy). When we first started, the easiest way to manage the public/private split seemed to be to set up a separate git repository for each project. We also had a top level repository, &lt;a href="https://github.com/OpenGamma/OG-Platform"&gt;OG-Platform&lt;/a&gt;, that contained the common top-level build files and configuration. The idea was that you cloned from OG-Platform and then cloned each sub-project into the projects directory underneath it.&lt;/p&gt;
&lt;p&gt;That worked relatively well until we got to about 10 projects, at which point we found that it took so long to commit changes across all projects that someone else had committed in the meantime and you had to merge again. We also found it was very easy to forget to sync up some of the projects and you’d get strange errors when a rarely used project was slightly out of date.&lt;/p&gt;
&lt;p&gt;To address these problems we did two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We merged all the Open Source projects (excluding &lt;a href="http://www.fudgemsg.org/display/FDG/Fudge+Messaging+Home"&gt;Fudge&lt;/a&gt;, the self-describing binary message encoding system we are the primary sponsors of) into a single repository, OG-Platform. OG-Platform would now contain all the Open Source projects in the projects directory straight away after a clone. This hugely reduced the number of repositories we needed to manage.&lt;/li&gt;
&lt;li&gt;We added some tools to perform operations across repositories. The ant task ‘clone-or-pull’ does either a clone, if the repository is not present, or a pull if it is. We later added ‘ant pull’ to do just the equivalent of ‘git pull origin master’ on every repository, and ‘ant status’ to do cross-project status reportings. Lastly we added a bash script ‘gitstats.sh’, which (parameter is the root directory, e.g. ‘.’) reports the status in a more compact tabular form.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Putting it all together for a public release&lt;/h3&gt;
&lt;p&gt;We still had a problem though: how to provide different sets of repositories to different users? For example, a user who was paying for our &lt;a href="http://docs.opengamma.com/display/DOC090/OpenGamma+Tools+for+Microsoft+Excel"&gt;Excel integration module&lt;/a&gt; might be able to access the code for that, but it isn’t part of our Open Source release. One approach would have been to just attempt to clone [or pull] each of the git repositories we had, and rely on the permissions to fail if it wasn’t available, but this felt ugly and could potentially lead to information leakage about our private client projects.&lt;/p&gt;
&lt;p&gt;To get around this we came up with a system that downloaded a small set of ant build and properties files from a web server, using HTTP authentication provided during the build. Open Source users would use one user name and password (the defaults offered), but commercial customers could use other user name and passwords to get customized build setups. This is where the ‘ant init’ task comes from. It allows the user name and password to be set either by the user as an environment variable, or specified on the command line via an interactive prompt.&lt;/p&gt;
&lt;p&gt;What this means is that we can now provide a completely customized set of projects to each customer based purely on a user name and password combination. And as long as we’ve set up their permissions in GitHub, they can clone the code to wherever they wanted.&lt;/p&gt;
&lt;p&gt;A slight downside, however, was that it added a step to an already fairly complicated build process. To address this, we’re changing the behaviour for 1.0 to default to the Open Source user name and password unless one is explicitly set up. We also made the clone-or-pull part of a single-step build process, meaning there’s truly one command after the initial clone to build a binary installation. Lastly, we’re changing Fudge, which is now pretty stable, to be an external dependency. This means that out of the box, the Open Source release only requires a single clone rather than three.&lt;/p&gt;
&lt;p&gt;What we’ve come up with seems to satisfy all our immediate requirements. It’s not perfect, and we considered many other approaches (e.g. sub-modules) before settling on this. With the right attention to detail in smoothing the path for Open Source users while allowing commercial customers access to the extra code they’re paying for, it seems to be a successful approach for us.&lt;/p&gt;
&lt;p&gt;Of course, there’s always more than one way to skin the cat. Have you faced similar issues in your project? How did you solve them? Share your experiences in the comments below.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/aMxgHGRs-5w" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/03/13/public-private-java-project-using-git</guid>
<pubDate>2012-03-13T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/aMxgHGRs-5w/public-private-java-project-using-git</link><feedburner:origLink>http://www.opengamma.com/blog/2012/03/13/public-private-java-project-using-git</feedburner:origLink></item>
<item>
<title>Open Source - And the Value of Becoming a Client</title>
<description>&lt;p&gt;As an Open Source business, we often get asked what our business model is (or, more directly: How do we make money?). I like that question because it invites us to talk about the relationship with our clients, which is probably the key element of what our commercial clients get and value.&lt;/p&gt;
&lt;p&gt;Open Source is not only a better way of developing and delivering software, it also allows for a much deeper relationship between the vendor and the client. The &lt;a href="http://www.opengamma.com/platform/radically-open"&gt;openness in code and architecture&lt;/a&gt; encourages openness in other areas too, and creates a more collaborative relationship.&lt;/p&gt;
&lt;p&gt;All the firms we work with - banks, hedge funds, inter-dealer brokers, etc. - are fed up with poorly-supported solutions with output from out-dated software that no longer reflects the needs of the people using it. Building in-house is an option, but it's becoming increasingly difficult with tight budgets and hard-to-hire talent. Most good investors realise that they aren't, and shouldn't be, great software houses. So an Open Source solution is a desirable alternative, providing the transparency and openness you get from an in-house system, with the development skills of a dedicated software firm.&lt;/p&gt;
&lt;h3&gt;No need to go unsupported&lt;/h3&gt;
&lt;p&gt;But Open Source doesn't mean you are on your own. With an OpenGamma subscription you get high-quality support and maintenance from relevant specialists who know your installation intimately.&lt;/p&gt;
&lt;p&gt;We have dedicated staff with deep technical knowledge supporting our clients. With specific insight into your installation, from initial set-up to on-going maintenance, upgrades and expansion, they are at hand to ensure you have a stable and current solution that evolves with the rest of your infrastructure and business activities.&lt;/p&gt;
&lt;h3&gt;Access to expertise&lt;/h3&gt;
&lt;p&gt;And we really don't like just giving you a phone number to call and pray someone is there if things go wrong. As part of our own learning experience, we would like you to call us not just when something fails, but also when you simply wish to exchange ideas, or question the way we've implemented a particular feature.&lt;/p&gt;
&lt;p&gt;When you call, you get access to the engineers who actually built the system, which is great for both parties. You can talk to someone who knows what they are doing and can explain why we have done what we've done (which of course is transparent), and we learn what our clients are working on and what matters to them.&lt;/p&gt;
&lt;p&gt;We believe this dialogue is much more than effective support. It forms an important part of the community - or ecosystem - of users and developers and benefits us all. We learn what's happening in the market and can share that with the community at large, as well as feeding it into the Platform to create a better solution.&lt;/p&gt;
&lt;p&gt;As we focus on the technical issues that are common to many, rather than that which is proprietary, we think this sharing of information helps all our users to understand what works and how, saving money and improving quality for all.&lt;/p&gt;
&lt;p&gt;The OpenGamma Platform is also &lt;a href="http://www.opengamma.com/platform/integration"&gt;designed for integration&lt;/a&gt;, with APIs to your other systems. This means we have a lot of experience working with different solutions and usually have a pretty good understanding of the relevant strengths and weaknesses of those we integrate with. We're not tied to other software or hardware vendors, but we are happy to share our views and recommendations with our clients.&lt;/p&gt;
&lt;h3&gt;Let's talk about quants&lt;/h3&gt;
&lt;p&gt;Another aspect of being a client is that you have access to our quants. This is a highly regarded team of quant specialists with diverse, but highly relevant backgrounds. They have all come to OpenGamma to be able to work on something that is state-of-the-art and has industry-wide impact. We love to offer them up to our clients who engage with them directly - sometimes clients come by for a "deep dive" chat, and sometimes to sound us out on how to generate the analytics for a certain trade for example.&lt;/p&gt;
&lt;p&gt;As with our developers, our quants are not here to replace you, but rather to provide the tools for you to do more and better.&lt;/p&gt;
&lt;h3&gt;Commercial transparency&lt;/h3&gt;
&lt;p&gt;The OpenGamma Platform can be installed in parts or enterprise wide. What is built to support large investment banks or huge hedge funds is also available to smaller firms, on a smaller scale. We typically don't charge large upfront fees, preferring instead to spread the cost out according to a clear subscription agreement that we negotiate upfront depending on the complexity of your installation and the level of involvement from us. You don't pay per-user licences or per-incident support fees, and we aim to make the cost both predictable and transparent. We are convinced the OpenGamma ROI is very compelling and would be happy to &lt;a href="http://www.opengamma.com/contact"&gt;discuss it with you in more detail&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, having access to the source code frees you from the tyranny of vendor dependencies. If you don't find being an OpenGamma client of value, there is nothing tying you to us; you are free to keep your installation and continue using the Platform! Kind of keeps us on our toes too.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/W0Ja6_pxHLY" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/02/15/becoming-a-client</guid>
<pubDate>2012-02-15T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/W0Ja6_pxHLY/becoming-a-client</link><feedburner:origLink>http://www.opengamma.com/blog/2012/02/15/becoming-a-client</feedburner:origLink></item>
<item>
<title>Bloomberg Opens Up Its Market Data API - OpenGamma 1.0 Release Being Prepared</title>
<description>&lt;p&gt;What a day for Open Source and the financial services industry at large: Bloomberg announced yesterday it is opening up its market data API under the open source MIT license - in stark contrast to its competitors.&lt;/p&gt;
&lt;p&gt;The implications for OpenGamma users are huge, and positive. We know many of you evaluating the software already have Bloomberg terminals available, yet due to Bloomberg's previous policy have been forced to rely on mock data. We've provided some of you with the integration module for evaluation purposes &lt;a href="http://www.opengamma.com/blog/2010/07/26/opengamma-and-open-core-components"&gt;under a proprietary license&lt;/a&gt;, but we also understand that many of you prefer to self-evaluate the product without having to contact us. Bloomberg's announcement will allow us to change that.&lt;/p&gt;
&lt;h3&gt;Where's 1.0?&lt;/h3&gt;
&lt;p&gt;We know you've all been anxiously waiting for the 1.0 release of our Platform. It's actually been broadly stable and feature complete for a while now; we already run it internally 24/7 and have firms using it in anger. The few remaining pieces are mostly related to &lt;a href="http://docs.opengamma.com/"&gt;documentation&lt;/a&gt; and examples.&lt;/p&gt;
&lt;p&gt;After yesterday's announcement, our goal is to go back and amend our 1.0 plans to include the Bloomberg Integration Module - we'd like to ensure there are evaluation tools ready with the upcoming release. As soon as the module is ready to be released open source - assuming this will happen before the 1.0 release - we'll aim to publish it on our &lt;a href="https://github.com/OpenGamma"&gt;GitHub account&lt;/a&gt;, as well as make an announcement on the &lt;a href="http://forums.opengamma.com/forum/"&gt;forums&lt;/a&gt;. The module will then allow anyone with a valid Bloomberg terminal or Server API instance to directly access Bloomberg data from within the OpenGamma Platform.&lt;/p&gt;
&lt;p&gt;We've been working on and with the OpenGamma Bloomberg Integration Module for several years now, and the difference in evaluation will be pretty extreme. Our goal is for you to be able to download the Platform, connect it to a Bloomberg Terminal running on your desktop, and have real-world analytics and risk in a matter of minutes. We think that's worth waiting a few more weeks for! (Want to make it happen faster? &lt;a href="http://www.opengamma.com/jobs"&gt;We are hiring&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;We are now working on the final preparations, and will be updating you shortly - &lt;a href="http://twitter.com/opengamma"&gt;stay tuned&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/rC40JkZ5Oj8" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2012/02/02/bloomberg-market-data-api-opengamma-1.0-release</guid>
<pubDate>2012-02-02T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/rC40JkZ5Oj8/bloomberg-market-data-api-opengamma-1.0-release</link><feedburner:origLink>http://www.opengamma.com/blog/2012/02/02/bloomberg-market-data-api-opengamma-1.0-release</feedburner:origLink></item>
<item>
<title>The Sparse Farce</title>
<description>&lt;h2&gt;What Was Said Last&lt;/h2&gt;
&lt;p&gt;In my last post I briefly outlined some performance gains we were achieving in our tuned dense BLAS library. Evidently this was received with mixed opinion! Tuning Java does seem like an insane idea, and indeed some people pointed this out, but given that these are our constraints:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Code has to be as fast as possible.&lt;/li&gt;
&lt;li&gt;Assume the hardware is fixed and tune to it.&lt;/li&gt;
&lt;li&gt;Code has to be in Java: no JNI, no hitting Fortran/BLAS/&amp;lt;insert thing we'd normally use here&amp;gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So we don't really have a lot of choice! Once every piece of algorithmic tuning has been taken into account, the main point of performance death is going to be JVM and the fact that the JVM doesn't provide primitives those of us from the scientific computing world are used to, both of which are immutable as selections. However, trying to force their combination to produce something reasonable performance wise (as exhaustively pointed out by the people at LMAX) requires effort in terms of the acknowledgment of the hardware and a trip back to basic computer science.&lt;/p&gt;
&lt;h2&gt;What's Next&lt;/h2&gt;
&lt;p&gt;Having been relatively successful with increasing performance in dense BLAS kernels, we turned our attention to the invariably hard sparse BLAS operations: It is our notes and observations on this topic that form the bulk of this article. For those unfamiliar with the notion of a sparse matrix, a sparse matrix is categorised as a matrix with a only a small number of non-zero elements (yes, defining small is part of the problem). Sparse matrices arise a lot in numerical methods and indeed as a result of certain mathematical operations which tend to create some form of diagonal dominance, but this is not strictly so. Additionally, there is no real condition on the pattern of the non-zero elements or what constitutes a sparse structure.&lt;/p&gt;
&lt;h2&gt;Why?&lt;/h2&gt;
&lt;p&gt;The reason that we categorise sparse matrices separately is for gains in both performance (we don't need to do operations involving zero entries) and memory foot print (we don't need to store zeros). For example, multiplying a sparse matrix by a vector should proceed as a linear function of the number of non-zero elements of the matrix as opposed to the dimension of the matrix. These performance gains can be carried over into other linear algebra operations but as we'll see later this is easier said than done, particularly with the utter lack of memory manipulation presented by the Java language.&lt;/p&gt;
&lt;h2&gt;Storage Formats&lt;/h2&gt;
&lt;p&gt;First, we shall address the manner in which to store the sparse matrix data. Most Java programmers when asked this question reach for a Map implementation, and rightly so, a &lt;code&gt;Map&amp;lt;Pair&amp;lt;row number, column number&amp;gt;, value&amp;gt;&lt;/code&gt; would certainly suffice and be very easy to use. The problem, as always with built-in overkill, is that it is probably slow. Notably, the more we play with getting performance from Java, the more we have come to the conclusion that if the Java code doesn't look like a variant of Fortran, it's going to be slow. So although a Map has some advantages, as we'll see later, the bloat is a speed killer.&lt;/p&gt;
&lt;p&gt;From the idea of a map, we deduce that to describe the matrix all that is needed is a tuple of &amp;lt;row number, column number, value&amp;gt;. The &lt;a href="https://github.com/OpenGamma/OG-Platform/blob/f2b15a0ab91249c18860c1f7df92d7924173ad15/projects/OG-Analytics/src/com/opengamma/math/matrix/SparseCoordinateFormatMatrix.java"&gt;Coordinate Format matrix (referred to as COO)&lt;/a&gt; is perhaps the most basic sparse matrix storage format and it directly reflects this tuple layout by storing the data as three vectors, two int pointers (one to row indices and another to column indices) and a double/float pointer to the corresponding value. Using the following matrix as an example:&lt;/p&gt;
&lt;pre&gt;
    1    3    0    0   12
    0    4    6    8    0
    2    0    0    9   13
    0    5    7   10   14
    0    0    0   11    0
&lt;/pre&gt;
&lt;p&gt;A COO matrix would store the data as:&lt;/p&gt;
&lt;pre&gt;
int[] columnIndex = {0, 1, 4, 1, 2, 3, 0, 3, 4, 1, 2, 3, 4, 3};
int[]    rowIndex = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4};
double[] data     = {1, 3, 12, 4, 6, 8, 2, 9, 13, 5, 7, 10, 14, 11};
&lt;/pre&gt;
&lt;p&gt;This example highlights two important points. First, the memory footprint of the stored data is larger than that of the original data (3*14 vs 5*5). Second, there is exploitable information redundancy in the rowIndex variable.&lt;/p&gt;
&lt;p&gt;Our next matrix format is the &lt;a href="https://github.com/OpenGamma/OG-Platform/blob/f2b15a0ab91249c18860c1f7df92d7924173ad15/projects/OG-Analytics/src/com/opengamma/math/matrix/CompressedSparseRowFormatMatrix.java"&gt;Compressed Sparse Row storage format (CSR)&lt;/a&gt;, which takes advantage of this redundancy by solely storing a row pointer from which it is possible to compute an offset into the data. This row pointer is formed by keeping a cumulative count of the number of non-zero data elements encountered up the start of a given row in the matrix. This is probably best described with an example, so continuing with the above matrix:&lt;/p&gt;
&lt;div class="og_widecontent og_unbordered"&gt;
&lt;pre&gt;
int[] columnIndex = {0, 1, 4, 1, 2, 3, 0, 3, 4, 1, 2, 3, 4, 3}; // This is the same as for COO
int[] rowPtr = {0, 3, 6, 9, 13, 14}; // This effectively stores a cumulative data count
double[] data = {1, 3, 12, 4, 6, 8, 2, 9, 13, 5, 7, 10, 14, 11}; // This is the same as for COO
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that the rowPtr variable contains (number of rows + 1) entries. This is to account for the number of elements in the final row and to allow easy computation of the number of elements in a row for the sake of induction variables that index in the column space. For example, to walk through the data in row 2 (assuming 0 based row indexing):&lt;/p&gt;
&lt;pre&gt;
int index = 2;
for (int i = rowPtr[index]; i &amp;lt; rowPtr[index+1]; i++){
  data[i]; // accessing data belonging to a row
}
&lt;/pre&gt;
&lt;p&gt;From this, is it clear that due to the storage of an additional rowPtr index, the same code can be used for all the rows, which considerably simplifies algorithms.&lt;/p&gt;
&lt;p&gt;In addition to the CSR there is an equivalent storage format whereby the rows and columns reverse roles such that offsets are computed by column, and rows are used to give the locations within each offset. This storage format type is known as &lt;a href="https://github.com/OpenGamma/OG-Platform/blob/f2b15a0ab91249c18860c1f7df92d7924173ad15/projects/OG-Analytics/src/com/opengamma/math/matrix/CompressedSparseColumnFormatMatrix.java"&gt;Compressed Sparse Column (CSC)&lt;/a&gt;. By inspection, it is obvious that CSR and CSC formats will have different total information content for non-symmetric matrices. However, both will have a lower information content than COO (in most real world cases).&lt;/p&gt;
&lt;p&gt;So we've visited the basic matrix storage formats for sparse matrices. Unsurprisingly they are also present in Python, GNU Octave and hardened system maths library collections like suitesparse. Now for the interesting bit...&lt;/p&gt;
&lt;h2&gt;Why Sparsity Is A Pain&lt;/h2&gt;
&lt;p&gt;Sparse matrices are an invariable pain to deal with. As demonstrated previously, it's possible to actually increase memory usage if the matrix is insufficiently sparse for the storage format chosen. However this isn't the main gripe with these matrices.&lt;/p&gt;
&lt;p&gt;The main problem arises from the fact that the code will execute on hardware and this hardware behaves in a certain way. Without going into the ins and outs of processor behaviour and memory hierarchy performance, the full deviousness of tasks involving sparse matrices is hard to explain. However, for now we need to bear in mind two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The processors can quickly access data so long as the next element to be used is stored in memory directly after the element presently being accessed.&lt;/li&gt;
&lt;li&gt;That operations are best pipelined by making use of a mix of instructions, and that for maximum throughput on the floating point units the data should be coalesced as SIMD operations (as seen in my previous post, SSE isn't that great in Java).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, if we take as an example the CSR format matrix "A", containing the information previously presented, and want to do a sparse matrix vector multiply operation (SpMV, as in, result:=A*x), we can use the following code:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/1446838.js"&gt;
&lt;/script&gt;
&lt;p&gt;Performing a bit of basic analysis on this algorithm with regards to points 1) and 2) above, we can note that the variable "x" is being accessed by the index dereferenced by the column index. This does not bode well for point 1) above. Although &lt;code&gt;values[], result[], rowPtr[] and colIdx[]&lt;/code&gt; are being indexed in a stride 1 fashion, "x" is not, and random data access is rather slow (pipeline stall, lack of hardware prefetching etc.) As to point 2), if the data cannot be fed to the floating point units fast enough, then their SIMD nature cannot be exploited (ignoring the lack of Java's ability to easily do this - it's a language invariant problem).&lt;/p&gt;
&lt;p&gt;To attempt to improve the speed of this operation, we threw the standard set of techniques at the code (loop unwinding, strip mining, etc) and even weirder attempts like trying to force prefetching via loop skewing/peeling and reducing indexing to single bytes. However, none of this could overcome the inherent slowness caused by poor locality of reference.&lt;/p&gt;
&lt;h2&gt;A Quick Look at Basic BLAS Results&lt;/h2&gt;
&lt;p&gt;For our own interest we compared the OG implementations of COO and CSR SpMV with equivalent operations from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://acs.lbl.gov/software/colt/"&gt;Colt&lt;/a&gt; - has sparse support and uses &lt;strong&gt;threaded&lt;/strong&gt; SpMV().&lt;/li&gt;
&lt;li&gt;&lt;a href="http://commons.apache.org/math/"&gt;Commons Math&lt;/a&gt; - has sparse support&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sourceforge.net/projects/ujmp/"&gt;Universal Java Matrix Package (UJMP)&lt;/a&gt; - has sparse support&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jscience.org/"&gt;JScience&lt;/a&gt; - has sparse support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following were not used (reasons given):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/efficient-java-matrix-library/"&gt;Efficient Java Matrix Library (EJML)&lt;/a&gt; - no support&lt;/li&gt;
&lt;li&gt;&lt;a href="http://math.nist.gov/javanumerics/jama/"&gt;Jama&lt;/a&gt; - no support&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jblas.org/"&gt;jblas&lt;/a&gt; - wrapper to native code, cheating!&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/matrix-toolkits-java/"&gt;Matrix Toolkit Java (MTJ)&lt;/a&gt; - no support&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ojalgo.org/"&gt;OjAlgo&lt;/a&gt; - no support&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sites.google.com/site/piotrwendykier/software/parallelcolt"&gt;Parallel Colt&lt;/a&gt; - wrapper to native code, cheating!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the tests we used a set of increasingly large matrices with a fixed sparsity and ran essentially &lt;a href="http://www.opengamma.com/blog/2011/10/14/maths-library-development"&gt;the same setup as before&lt;/a&gt; (harness code thrashes cache, warms up JVM, does multiple timings. Machine is a reasonable desktop machine). The results we obtained are below, each pair of graphs corresponding to the percentage of non-zero entries as given in their titles. The horizontal axis of each graph indicates the matrix size being tested (matrices were square n x n). The graphs in the left column present the raw timings obtained and are plotted on a log&lt;sub&gt;10&lt;/sub&gt;() scale in the vertical axis. The graphs on the right show the relative speeds of the sparse matrices from the tested packages (as mentioned above) against the two OpenGamma sparse matrix types, the dashed lines are comparing against OpenGamma COO and the solid lines against OpenGamma CSR, again the vertical axis is at log&lt;sub&gt;10&lt;/sub&gt;() scale. The plots referring to 25% and 50% non-zeros are missing results from the jScience implementation as the run times were so long (running into days) that we stopped them!&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/TimeSpMV1pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/TimeSpMV1pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/SpeedupSpMV1pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/SpeedupSpMV1pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/TimeSpMV10pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/TimeSpMV10pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/SpeedupSpMV10pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/SpeedupSpMV10pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/TimeSpMV25pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/TimeSpMV25pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/SpeedupSpMV25pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/SpeedupSpMV25pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/TimeSpMV50pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/TimeSpMV50pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/SpeedupSpMV50pcnz.800.png" rel="lightbox"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/SpeedupSpMV50pcnz.250.png" alt="" width="250" height="188"/&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As a small post analysis, maps have an advantage in that adding elements is relatively easy whereas adding elements to CSR or COO is less so and can involve some quite expensive &lt;strong&gt;memcpy()&lt;/strong&gt;ing, evidently we haven't tested the performance of this yet! However, if the data structure is immutable, as it often is in numerical applications (as a result of some properties of a numerical model, i.e. element density and ordering), then operations involving the fixed sparse matrix are of more importance. Furthermore, a large number of numerical methods rely on the repeated computation of matrix vector products, for example, a huge number of Krylov subspace methods, and so it is of importance that this kernel is fast. Evidently it is this sort of operation that was tested above and the OpenGamma implementations perform relatively well. It is also interesting to note that throwing threads at the problem, as done in the Colt library, does not actually increase the performance of the operation unless sufficient arithmetic density is available within the data set. This result can be seen first in the n=900 and n=1000 matrices with 10% non-zeros, it is at this point that sufficient work is present for the threads to be kept busy (perhaps as a result of the less false-sharing or better out of core cache characteristics). Finally, for reference, an additional screen shot of jConsole (below) shows that the CPU usage is incredibly poor and this is like due to the poor locality of reference which inherently hinders the floating point operations (the sudden jump in the number of threads used is due to the threaded Colt library).&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://og-web-www.s3.amazonaws.com/jconsole.800.png" rel="lightbox"&gt;&lt;img class="boxed" src="http://og-web-www.s3.amazonaws.com/jconsole.500.png" alt="" width="500" height="771"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Things That Are Going To Make Life Hard&lt;/h2&gt;
&lt;p&gt;This leaves us in an interesting place, and it turns out that solving the previously discussed locality of reference problem also assists with other associated problems occurring in functions such as matrix decompositions. Given that most whole matrix operations can be rewritten in terms of a row or column permutation of the matrix (assuming infinite precision arithmetic) we can try to apply techniques to create a more amenable form with respect to a given performance model. For example, in the case of matrix vector multiply, it would be ideal if we could find a permutation that moved the data in such a way that contiguous blocks formed near the diagonal such that at least some stride 1 access in the "x" vector were possible. It turns out that a similar behaviour is also needed for algorithms such as sparse LU decomposition and sparse Cholesky decomposition. This is to reduce the number of fill-ins (writing data to an originally non-zero part of the matrix structure) caused; basically the same permutation idea but this time with a different optimisation criterion. Amusingly it transpires that this problem is NP-Hard. However, in large part thanks to the GPU community considerable research has continued into this area as any poor locality of reference problem on a CPU is considerably worse on a GPU. Furthermore, a number of further highly specialised storage formats making use of combinations of compressed sparse row, blocks and multiply packed indexes have been derived. These formats will also increase performance but generally rely on permutations found by attempting to solve the NP-Hard problem and having a sufficiently high level of arithmetic intensity (due to a lot of data!) such that reordering and branching code costs can be amortised.&lt;/p&gt;
&lt;p&gt;To demonstrate a possible bandwidth reduction on the previously used matrix, the permutation A(P,P) as given below tightens the matrix around the diagonal thus increasing the possibility of performance gain.&lt;/p&gt;
&lt;pre&gt;
P = { 5   1   3   4   2 }

A(P,P) = 12    0    9    0    0
         11    1    7    0    0
          0    0    0   10    5
          0    3    8    0    6
          0    2    0    0    4
&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Essentially we reach an impasse. We are currently working on bandwidth-reduction and fill-in reduction algorithms to try and increase the performance possibilities within the sparse classes. Sparse decompositions are also a rather challenging area programmatically partly due to the algorithmic complexity required (building permutations, computing up-date trees, pruning trees, updating partial matrices, etc.), and partly due to the lack of pointers in Java making life generally hard work. Still, we shall persevere, and next time I write we should hopefully have some working prototypes.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/SYvY5xJdLZI" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2011/12/21/the-sparse-farce</guid>
<pubDate>2011-12-21T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/SYvY5xJdLZI/the-sparse-farce</link><feedburner:origLink>http://www.opengamma.com/blog/2011/12/21/the-sparse-farce</feedburner:origLink></item>
<item>
<title>First R Sample - Market Data Plotting</title>
<description>&lt;p&gt;We've been overwhelmed since we went public with the OpenGamma Platform with the number of developers, analysts, and risk managers who want to combine our data management and calculation capabilities with the statistical power of the R environment.&lt;/p&gt;
&lt;p&gt;Much like we decided to actively embrace Excel as a front-end for driving an OpenGamma Platform installation, we thought that if people wanted to use R, it was up to us to make sure that we had the best support for it possible.&lt;/p&gt;
&lt;p&gt;As the first public sample of just what we're getting at, consider the &lt;a href="http://www.quantmod.com/examples/chartSeries3d/"&gt;ChartSeries3D&lt;/a&gt; component. The example they provide is plotting a year's worth of yield curves, a pretty ideal way to showcase that rather than pulling this data from a file, you can pull it directly from the Historical Time Series service in an OpenGamma Platform installation.&lt;/p&gt;
&lt;p&gt;I wanted to start with perhaps the simplest thing possible: plot the market data points that form your yield curve definition over the course of a year.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;img src="http://og-web-www.s3.amazonaws.com/yieldcurve-small.jpg" alt="Yield curve" width="538" height="217"/&gt;&lt;/p&gt;
&lt;p&gt;All that from this relatively small sample of R code:&lt;/p&gt;
&lt;script src="https://gist.github.com/1336987.js?file=YieldCurve.R" type="text/javascript"&gt;
&lt;/script&gt;
&lt;p&gt;In the next installment, I'll show you how we've modified this example to not only plot the raw market data, but to actually fit the yield curve using the OpenGamma Analytics library from data loaded into the R environment, and then bring back the fully fitted yield curves for plotting.&lt;/p&gt;
&lt;p&gt;And that's before we show you the real power of what we're doing: driving full shocks, stresses, and historical regressions of whole portfolios from R and using R to analyze the results. We think R users in finance are going to find this exciting.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/aVdKeoUsH_U" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2011/11/03/first-r-sample-market-data-plotting</guid>
<pubDate>2011-11-03T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/aVdKeoUsH_U/first-r-sample-market-data-plotting</link><feedburner:origLink>http://www.opengamma.com/blog/2011/11/03/first-r-sample-market-data-plotting</feedburner:origLink></item>
<item>
<title>OpenGamma Maths Library Development Kicks Off In Earnest</title>
<description>&lt;p&gt;I'm a new face here at OpenGamma, having joined this summer, and I wanted to introduce myself and what I'm doing here. My job here can be stated simply: make the OpenGamma maths library as fast as possible!&lt;/p&gt;
&lt;p&gt;Having come to OpenGamma with a background in applications of high performance and accelerated computing in numerical modelling, I have a fair idea about how to make code performing mathematical operations run fast. However, doing this in Java as opposed to my beloved Fortran or C is a completely different game.&lt;/p&gt;
&lt;p&gt;First, some comments about why on earth we are doing maths in Java. Well, "write once, run everywhere", coupled with the rather magic IDE behaviour of Eclipse (although I still prefer vi ;-)) means that the code written can be guaranteed to run without having experts in cross-platform compiling around to deal with any issues. The Eclipse editor also makes unit testing, debugging and general code writing considerably less error prone. Java also has the ability to call out to native code via JNI or JNA, both of which can be used in the future, should the maths library interfaces be written in a sane manner conducive to their integration.&lt;/p&gt;
&lt;h2&gt;What currently exists for maths in Java?&lt;/h2&gt;
&lt;p&gt;There are a number of well-established maths libraries for use in Java. Two of the most commonly used are &lt;a href="http://acs.lbl.gov/software/colt/"&gt;Colt&lt;/a&gt;, and &lt;a href="http://commons.apache.org/math/"&gt;Apache Commons Mathematics&lt;/a&gt;, and it is these libraries that we currently use in-house. Having briefly looked through the source code, there are some features/methods that are lacking (for example, more advanced gradient-based linear system solvers) and experience suggests that the performance (in terms of speed) of these libraries is not particularly good in comparison to native code (expected) or more heavily tuned Java code (as will be seen later). On the positive side, both libraries are tried and tested and have different, but relatively easy to use, APIs.&lt;/p&gt;
&lt;h2&gt;Why do we want a new maths library?&lt;/h2&gt;
&lt;p&gt;At OpenGamma speedy maths is essential. Financial analytics uses a wide range of numerical techniques from very simple models and operations (basic integration and curve fitting) through to the considerably heavier traditional numerical modelling techniques. Clearly these models have to run in near real time or at least fast enough that their execution completes between ticks so that new analytics can be displayed soon after data arrives down the wire. Obviously, to achieve this, speed is key.&lt;/p&gt;
&lt;h2&gt;How are we writing the new maths library?&lt;/h2&gt;
&lt;p&gt;A large number of mathematical operations are essentially matrix related and in acknowledgement of this, the industry standard BLAS APIs are quite wonderful as building blocks. Furthermore, evidence of the importance of this API comes from the chip vendor specific implementations of BLAS (along with extensions to sparse matrices and FFTs). Sadly, there is no complete and heavily optimised BLAS library for Java. This is where OpenGamma comes in.&lt;/p&gt;
&lt;h2&gt;So what exactly are we doing?&lt;/h2&gt;
&lt;p&gt;In the last few months I have been working on identifying code patterns and techniques that the JVM can spot for optimisation. In general, these techniques are relatively simple and already well known, and are extensively used in the high performance scientific computing world. I've been concentrating on BLAS operations, specifically &lt;a href="http://www.netlib.org/blas/dgemv.f"&gt;DGEMV()&lt;/a&gt; with alpha = 1 and beta = 0 such that the operation is essentially:&lt;/p&gt;
&lt;pre&gt;
y:=A*x 
&lt;/pre&gt;
&lt;p&gt;where y is a [m x 1] vector of doubles, A is a [m x n] matrix of doubles and x is a [n x 1] vector of doubles.&lt;/p&gt;
&lt;p&gt;Following this, a naive implementation of the operation can be written, and it is this version that appears in many Java linear algebra libraries:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/1275719.js"&gt;
//
//  // 
//
&lt;/script&gt;
&lt;p&gt;So, from here we applied a whole load of optimisation magic and we've outlined this in a paper that you can &lt;a href="http://developers.opengamma.com/articles/DGEMV.pdf"&gt;download from here&lt;/a&gt;. Have a read; most optimisations aren't too hard to do and we found out some interesting things about the JVM.&lt;/p&gt;
&lt;h2&gt;Results:&lt;/h2&gt;
&lt;p&gt;In general, it is nice to know that it is possible to improve the speed of code, and indeed knowing what happens in the metal is worthwhile. All the results relate to the computation &lt;code&gt;Y:=A*x&lt;/code&gt; for square matrix A of varying size. Implementation details can be found in the previously mentioned paper.&lt;/p&gt;
&lt;h2&gt;Comparison to Colt and Apache Commons Mathematics:&lt;/h2&gt;
&lt;p&gt;The purpose of this investigation was to find out if it was possible to improve on naive implementations of a simple BLAS operation, and to provide comparison to the Colt and Apache Commons Mathematics libraries. Results from racing OpenGamma code operating on fairly typical matrix sizes, against a) a naive &lt;code&gt;double[][]&lt;/code&gt; backed matrix implementation b) Colt library c) Apache Commons Mathematics library are displayed below.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a rel="lightbox" href="http://og-web-www.s3.amazonaws.com/raw_ave-sized.png"&gt;&lt;img class="boxed" src="http://og-web-www.s3.amazonaws.com/raw_ave-small.png" alt="Comparing y:=A*x. Average execution time." width="500" height="375"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From this graph we can see that OpenGamma code runs on average at least 1.6x as fast as Apache Commons Mathematics. Furthermore, the OpenGamma code consistently runs at over 2x the speed of the Colt library code and peaks at around 2.4x. These comparisons demonstrate what is possible if you push Java hard and they give a hint of what is to come... watch this space, maths is about to get fast!&lt;/p&gt;
&lt;h2&gt;Update on 18 October, 2011&lt;/h2&gt;
&lt;p&gt;Based on a number of discussions on mailing lists and websites, we wanted to provide some common questions and answers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question: Why is OpenGamma not just using XYZ that already exists to provide BLAS?&lt;/strong&gt;&lt;br/&gt;
Answer: In al cases we have found so far either the adaptability, the possibility of interfacing with native libraries, or the performance has been insufficient for what we want/need, hence us writing our own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question: Why not just use the netlib Java interface to native BLAS or the netlib f2j translation of BLAS?&lt;/strong&gt;&lt;br/&gt;
Answer: We are fully aware of this project. To use a native BLAS, the calls have to go through the Java Native Interface (JNI). All calls through the JNI incur a penalty from crossing the JVM-&amp;gt;native barrier and there is uncertainty over the cost of this jump. Clearly, for some BLAS1 (and perhaps some BLAS2/3) calls on smaller data sets, the cost of accessing native libraries will be prohibitive. Therefore, the interface would need tuning to be performance optimal, on top of resolving and difficulties with running native libraries alongside Java. As to using the f2j translation of BLAS or the higher level netlib-java API (MTJ), we really want to have something that performs access directly on native types and can be performance tuned and don't feel that MTJ offers this opportunity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question: Why not just write in native code/use a native BLAS?&lt;/strong&gt;&lt;br/&gt;
Answer: We want to keep everything in Java for now; by doing this users can just download one package to get a system that JustWorks(TM). We are writing our library in such a way that jumping out to a tuned BLAS library when it becomes efficient to do so (in terms of setup time/user experience) will not be a problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question: Why do I get different performance results on my machine?&lt;/strong&gt;&lt;br/&gt;
Answer: Different hardware+JVM combinations are going to produce different performance results. The specification of the hardware+JVM we used is given in the above paper. The hardware we used is a fairly powerful number cruncher and so may well give better results for maths performance. Also, factors like how "warm" the JIT is, how much garbage collection goes on and how much heap is allocated will also affect the performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question: These optimizations are really basic. So what?!&lt;/strong&gt;&lt;br/&gt;
Answer: Correct, they are basic! It doesn't mean that they don't work though. Part of the investigation was to see which optimisations were available by default within the JIT and what could be coaxed out of the JIT with a bit of effort. We are fully aware that tuning to hardware is not a very Java like approach, but given the constraints (performance+staying in Java), it is something we are investigating and believe can be made to work.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/OpenGammaBlog/~4/98FDwwyx5D4" height="1" width="1"/&gt;</description>
<guid isPermaLink="false">http://www.opengamma.com/blog/2011/10/14/maths-library-development</guid>
<pubDate>2011-10-14T00:00:00</pubDate>
<link>http://feedproxy.google.com/~r/OpenGammaBlog/~3/98FDwwyx5D4/maths-library-development</link><feedburner:origLink>http://www.opengamma.com/blog/2011/10/14/maths-library-development</feedburner:origLink></item>
</channel>
</rss>

