Last night I got a demo of the brilliantly innovative IR derivatives Pricing Monkey system from the founder team. It prompted some thoughts on the cyclical nature of the software industry, and the return of the fat client. Back in the 90s, when Microsoft still ruled the world, client server computing and the fat client were the dominant model for application development. Often the server tier was simply a DB,  and all app logic happened in a Windows app built in MFC C++ or VB. The rise of Java and the browser threatened that model, and met with a forceful response from Microsoft. That’s a well-worn story, and I won’t repeat it here. Java never delivered on its promise of zero deploy desktop OS agnostic apps; anyone remember Marimba? Instead the browser began its long march toward becoming the dominant desktop client. After the dot com bust it took time for web 2.0 to emerge. For a while there was a debate about Silverlight vs Flex vs Ajax. Thankfully Ajax – the only one not aligned with a major vendor – won out, despite myriad incompatibilities between browsers and unsatisfactory server push mechanisms. Websockets and HTML5 resolved those issues, setting the scene for thin client zero deploy nirvana. Or so it seemed.

Concurrently with these technical developments on the desktop we’ve seen the rise of SaaS. The advance of the browser as client enabled ISVs, starting with SalesForce, to bypass corporate IT departments and server rooms, and deliver apps direct to users, often with UI quality approaching consumer products, and very low entry prices. Now there’s no end of CRM, budgeting and financial management, project management and industry specific vertical solutions delivered direct from cloud hosting to user desktops. Each browser delivered SaaS may be cheap and compelling, but they exclude the possibility of integration and data sharing across apps. Unless the business users buying those SaaS apps gets their IT department involved again to build integrations across the SaaS REST APIs. But that ain’t gonna happen, because the users bought into the SaaS apps to free themselves from the dysfunctional IT depts in the first place, and because of that the IT depts hate the SaaS apps in the same way they hate Excel.

So how does the integration problem get solved? On the desktop of course! We’re now seeing the re-emergence of 90s style app to app interop on the desktop. This time the enabler is not Microsoft’s OLE (Object Linking and Embedding), but proprietary extensions to the HTML5 container. OpenFin’s Chromium based HTML5 container supports drag and drop between apps, and also provides a pubsub bus. DDE anybody? This trend is writ large with Pricing Monkey’s IRD options pricing solution, which addresses the financial sector’s rates options trading niche in a fiendishly clever manner. Anyone who’s ever stepped on a trading floor knows about the ubiquity of the Bloomberg terminal. Bloomberg’s terminal comes with desktop interop; their Excel addin enables live ticking market data in spreadsheets. APIs do the same for desktop apps, but license terms mean that data can only be used by apps running on the same desktop. That precludes publishing Bloomberg market data to the server side pricing systems typical in the bigger hedge funds and banks. Pricing Monkey’s master stroke is to deliver IRD options pricing in a browser client, as an SaaS, and driven by Bloomberg market data. The analytics – the number crunching special source – are coded in JavaScript and run in the browser. Truly a browser based fat client offering a unique solution enabled by desktop integration.

We’re going to see more and more of this kind of SaaS delivered HTML5 fat client adding value with smart desktop integrations. Proprietary extensions like those in OpenFin, or Pricing Monkey’s Bloomberg integration, will multiply. Proprietary extensions will inevitably clash, and the benefits of zero touch deployment to a standardised HTML5 browser client will be dissipated. It’s all yet another instance of the endlessly repeating cycle in our industry: standards consolidate, and competition differentiates. Standards are introduced to ameliorate the pain of incompatibility, then vendors differentiate with proprietary extensions until the level of incompatibility becomes too painful and the cycle repeats. Intelligent market participants should think hard about where we are in the cycle, and how to get ahead of it. But not too far ahead of course!

Advertisements

Back in April I read a great post by Jaakko Piipponen on the SaaS financial model he’d built as an Excel spreadsheet. I’m interested in spreadsheet financial models, so I enjoyed Jaakko’s run down on how his model covers PnL report, operating expenses, payroll and revenue. Jaakko describes how you only need to spend 30 mins a month downloading reports from the Baremetrics dashboard and pasting it into Excel to keep it up to date. The post is titled an “SaaS financial model you’ll actually update”, because the value of the model is such that 30 mins of manual handle turning a month is more than justified. Now I’m the first to advocate Excel for business agility; it’s a great tool that enables sales, marketing and finance people to solve problems for themselves without the bottleneck of a software development team. But the downside of Excel is manual operation like the download and paste Jaakko spells out. Wouldn’t it be great if the Baremetrics data in the spreadsheet downloaded and updated automatically? Then the model would always be up to date, and no tedious and error prone download’n’paste operations are necessary.

So I built it by adding Baremetrics functions to my open source XLL Excel Addin SSAddin. Here’s a spreadsheet that strips Jaako’s model down to just the revenue parts of the model…

https://github.com/SpreadServe/SSAddin/blob/master/xls/flight_bare_model2.xls

It uses SSAddin functions to automatically download the revenue numbers every 10 minutes into the MRR Export sheet via the Show Summary API so the Revenue Model sheet will update every 10 minutes with the latest new customers, subscriptions, cancellations, upgrades and downgrades. All you need to do is download SSAddin 32 or 64 bit .xll binaries from here…

http://spreadserve.com/s3/downloads.html

Then install the addin in Excel and fire up the spreadsheet. Don’t forget to ensure that auto calc is on, and that you’ve got a copy of SSAddin.xll.config from the download page and put it next to SSAddin.xll on your PC. You’ll need to edit the .config to add your Baremetrics license key.

You can see flight_bare_model2.xls running online and driven by spreadserve.com data here…

http://sscalc0.online/flight_bare_model2.xls/0

http://sscalc0.online/flight_bare_model2.xls/MRR%20Export

This online spreadsheet takes automation to the ultimate level. When you run a spreadsheet model automated with SSAddin on your desktop or laptop you still have to start Excel, load the spreadsheet and hit F9 before auto updates can start. With SpreadServe hosting, you can move the spreadsheet onto a cloud server. All manual operations are eliminated, and everyone sees the same auto updating numbers in their browsers.

The SpreadServe 0.4.2b AMI is now available in the US West Oregon region: just search for SpreadServe in public images. There’s a now YouTube video on launching a SpreadServe AMI.

Two points of interest came up in preparing the AMI: Admin password persistence, and the region bound nature of AMIs. This blog from 2013 suggests that Admin passwords don’t persist in AMIs, but I’ve found they do now. So the Administrator password for a SpreadServe 0.4.2b AMI is SpreadServe042b. If you launch your own SpreadServe instance using the AMI, then I suggest you change the password!

The SpreadServe 0.4.2b AMI is only published in the US West Oregon region. Only AMI owners can copy to another region, so if you want a SpreadServe AMI in another region you’ll need to do a simple workaround: start an image in US West Oregon, stop it and create your own image, then copy to your preferred region.

This week I’ve been testing the SpreadServe addin with Tiingo’s IEX market data. I was checking performance on my sscalc0.online AWS host for a group of SpreadServeEngines executing various test and demo spreadsheets, including one that subscribes to IEX tickers for AAPL & SPY, via Tiingo API websockets. That API gives us real time top of book as well as last trade price and size for the cash equity traded on IEX. In my test scenario I was running five engines, two of them idle, three running spreadsheets, one of which was a simple IEX market data subscriber. Using Process Explorer I saw some odd CPU spiking on the idle engines. Zooming in with Process Explorer I could see the busyness was on a thread that should have been idle, sleeping inside a WaitForSingleObject call, waiting for a signal to check its input queue. The event object waited upon was created by some generic code invoking win32’s CreateEvent and also used in another thread. Reading the docs I found that CreateEvent’s fourth param, the event object name, implies that the caller will get a handle to a previously created event object if the names match. And I was using a hardwired name! So my thread was being repeatedly woken by events from another thread. A quick fix to make the names unique produced idling engines with no unnecessary CPU burn. All very instructive, partly because running on AWS makes one very aware of paying by the CPU hour.

SpreadServe AMI part II

January 17, 2017

The core component in a SpreadServe deployment is the SpreadServeEngine, a headless C++ server binary that implements the Excel compatible calculation engine. The engine discovers its hostname through the win32 API using GetComputerNameExA( ComputerNameDnsFullyQualified, …). On AWS this was giving me hostnames like WIN-THU4IQNRN6F, when what I wanted was the fully qualified domain name, like ec2-54-186-184-85.us-west-2.compute.amazonaws.com. Harry Johnston helpfully advised on StackExchange that, since the host is not joined to a domain, GetComputerNameExA will only return the FQDN if I explicitly set it via Control Panel. Naturally I want to avoid manual fixes on a SpreadServe AMI so I settled on using Amazon’s EC2 instance metadata. The FQDN hostname can be discovered with an HTTP GET on this URL from any EC2 host: http://169.254.169.254/latest/meta-data/public-hostname. I built a small helper server process to query instance metadata using Tornado’s async HTTPClient and write it to the localFS, where SpreadServeEngine can read it. Result: any new SpreadServe AMI will automatically discover its public DNS.

SpreadServe AMI part I

January 16, 2017

Recently I’ve been working on building an EC2 AMI for SpreadServe, so deployment becomes a one click operation for Amazon AWS users. I ran into an interesting snag so I thought I’d capture it here. My aim was to deploy SpreadServe as a Windows Service on an AWS Windows Server 2012 R2 image, so I used pywin32‘s excellent win32service module. Here’s my github boilerplate project for a Windows Service in Python. On my AWS host my SpreadServe Windows Service was failing to start, and leaving no trace in the system or application event logs. pywin32service has a debug mode; when I tried that I got a Windows 0xc00007b error, which indicates a mix of 32 and 64 bit binaries. SpreadServe is 32 bit all the way, so something was wrong. I turned to procmon to try and figure what was failing. procmon showed that my 32 bit pythonservice.exe was loading a 64 bit python27.dll, instead of the 32 bit python27.dll that’s part of the SpreadServe install tree. The 64 bit DLL was coming from the C:\Program Files\Amazon\cfn-bootstrap directory, which is added to the standard Windows 2012 R2 image by Amazon to support CloudFormation, and is on the system path. After much experimenting I couldn’t find a way to stop Windows Service Host from using the system path, so I had to change it to replace cfn-bootstrap with SpreadServe directories. Problem solved…