LINQ Custom Providers

By bposerow

I will be giving a talk tomorrow at .NET Code Camp in Stamford, CT.

The presentation, which I had previously given, is located here.

For this presentation, I had developed a sample LINQ provider that queries Yahoo Finance for some basic stock and stock option information and forms simple associations between them. I cheated a little bit and used Google Finance for one small piece of this as well.

Lessons learned:

  • Writing a LINQ provider is quite hard. LINQ basically is providing you something like a framework for compilation of a fairly restricted language, but you are building part of a compiler nonetheless, which is never easy.

    Specifically the .NET compiler compiles your LINQ query into something called an expression tree, which is a static representation of the LINQ query code, e.g. what filters are applied by the query, what kinds of objects is it selecting, etc. So the parsing of the query is done for you. But you are responsible for the translation and execution of the expression tree, i.e. the actual calls to the real data source, whether this is a web service, database, API, or anything else.

  • Using a LINQ provider is really easy. This is the most important part. You learn LINQ once, and then you know how to use pretty much any LINQ provider.

    Look how easy it is to use my new LINQ provider:

    from stockOption in optionContext.Query
    join stock in stockContext.Query on stockOption.UnderlyingStock equals stock
    where (stock.Symbol == "IBM" && stockOption.Strike > 35
                    && stockOption.Premium > 5)
    select new {stockOption.Symbol, stockOption.Premium,
                    StockSymbol = stock.Symbol,
                    stockOption.Strike})
    

    First a small bit of financial knowledge. An option is a right but not an obligation to buy or sell a certain amount of some underlying
    instrument, in this case stock for a certain price. It is time limited (it must be exercised by a certain date or it expires). So for
    a stock option, the underlying instrument is a stock. The strike price of an option is the price at which you now have to right to buy or sell the stock. So if I have an option to buy IBM stock for $50 by November 1, and the price of IBM stock rises to $65 on October 15th, I may choose to exercise the stock option. This would allow me to buy the IBM stock for $50, rather than the $65
    current price of the stock. I could also choose to wait it out, thinking that IBM stock might dip below $50, in which case I could buy
    it for cheaper than $50. However, if the option expires (we pass November 1st) and I have not executed it, the option expires worthless. One other note: the option also has a premium, which is the price I have to pay to obtain the option. Even if the
    option becomes worthless, the most I could pay out of pocket is the premium.

    It is easily explained what the query is doing above. I am finding all options currently available with the underlying stock “IBM” and then finding all stock options for IBM that have a strike price greater than $35 and for which the premium is greater than $5. I then return a list of anonymous objects, something like a tuple, that contains the stock symbol, the stock option symbol, and the stock option premium and strike price. I return one result for each stock option that matches the criteria.

    The key thing here is that while you had to have a little bit of business/domain knowledge to understand the query, you really did not require technical knowledge beyond basic LINQ knowledge to understand it. Furthermore, you didn’t even really need LINQ knowledge to understand it, because it looks so much like standard SQL.

    So it is clear (at least anecdotally) that LINQ is designed with the assumption that a few developers will experience the pain of creating providers with the understanding that the masses will benefit from simplicity of use.

Leave a Reply