The World’s Leading Microsoft .NET Magazine
   
 
The .NET Addict's Blog

My Top Tags

                                                           

My RSS Feeds








Latest Diggs - Programming

Internet Blogs - Blog Top Sites

Site Hits

Total: 2,551,710
since: 19 Jan 2005

Detailed Lambda Example - Building a VWAP Function

posted Tue 19 Feb 08

Every so often, I will get an e-mail from someone asking me to show them a good example of Lambdas in action in C# 3.5. When I go looking for lambda samples, I usually find some pretty interesting ones, but by and large they are relatively simple and don't really show you the power of lambdas, nested lambdas, and using lambdas within other language extensions.

One of the most key things to remember is that a lambda is data. It can be passed around as a function parameter. Most people like to think of lambdas as strongly typed function pointers and, in that light, they can be pretty easy to understand. The sample I want to show you is a lambda implementation of a pretty typical financial algorithm, VWAP. VWAP (Volume Weighted Average Price) is really just a way of measuring the average price of a stock, but using the volume of the trades done in a time series as a weight. So, if you have 1 trade done for 500 shares @ $50, the VWAP is $50. Add to it 300 more shares done at $75, and your VWAP is much closer to 75 whereas a traditional average would be right at $62.50. To people trading stocks, the VWAP value is often more important than the unweighted average.

Anyway, here's a lambda that figures out the VWAP. It operates on any IEnumerable and actually takes 2 lambdas as parameters. These input parameters instruct the VWAP function how to find the property on an object containing the quantity, and the property on an object containing the price.

Func<IEnumerable,
    Func<object, double>,
    Func<object, double>,
    double>
    VWAP =
    (series, priceSelector, volumeSelector) =>
    {
        int totalVolume = 0;
        double totalWeightedPrice = 0.0;
        foreach (object o in series)
        {
            double weightedPrice = priceSelector(o) * volumeSelector(o);
            totalWeightedPrice += weightedPrice;
            totalVolume += volumeSelector(o);
        }
        return totalWeightedPrice / totalVolume;
};

The syntax might actually look a little weird if you've never seen lambdas in C# before. In particular, priceSelector(o) and volumeSelector(o) give people trouble when seeing them for the first time. Both of those are actually lambdas, and what you're looking at is an invocation of the function pointer using o as an argument. These lambdas, as defined by VWAP, return a double value when passed an object. priceSelector returns a double value indicating the price stored on object o and volumeSelector returns a double value indicating the quantity stored on object o. You can see how this is used in a sample invocation of the lambda below:

double vwapResult = VWAP(allTicks,
    source => ((Tick)source).Price,
    source => ((Tick)source).Quantity);

The line:

source => ((Tick)source).Price

Can be roughly translated into, "for all values source, return source.Price where source is an instance of Tick". This is typically referred to as a selector or column selector lambda. You'll see stuff like this used extensively in LINQ, LINQ to SQL, and LINQ to Entities.

One of the things that really makes VWAP useful is that you can look at the VWAP throughout the course of the day. Wouldn't it be great if you could print to the console (or maybe render in a graph...) the VWAP value at the point each tick? Here's how you can invoke a lambda directly inside a language extension (in this case, ForEach):

allTicks.ForEach(
    tick =>
    {
        Console.Writeline(
            VWAP(allTicks.Take(allTicks.IndexOf(tick) + 1),
            source => ((Tick)source).Price,
            source => ((Tick)source).Quantity));
    });

I realize it's a little densely packed in there, but it's basically just running a loop through all of the ticks received and computing the VWAP based on the list of ticks up to that point so far, showing you a progressive change in VWAP since market open (or whatever your starting point was).

Anyway, I hope this quick demo of some "real world" lambdas has helped moreso than some of the typical "Hello World" lambdas that might be floating around.

tags:          

links: digg this    del.icio.us    technorati    reddit




1. Christopher Bennage left...
Tue 19 Feb 08 9:17 pm :: http://www.bluespire.com/blogs

Excellent example! Feel free to keep them coming!


2. kurrent_93 left...
Mon 05 May 08 3:46 pm

thanks very much, this helped me a lot to understand Lambda expressions.

Could you possibly do an example of showing the Open, High, Low and Close ? That would make me a very happy person! I have spent the past few weeks trying to figure that out.


3. kurrent_93 left...
Mon 05 May 08 3:49 pm

Open, High, Low and Close for a given time persiod, say 15minutes. I have been trying to create an app (using LINQ, but I think I will try with Continuous LINQ now) to show price candles.


4. Kevin Hoffman left...
Mon 05 May 08 6:54 pm

If you download the latest release of Continuous LINQ (http://www.codeplex.com/clinq), you'll notice that version 1.1 includes a stock monitor demo. This demo not only uses CLINQ queries for filtering the book down to one symbol, but it is also using continuous aggregates (a new feature in 1.1) to illustrate the current high, current low, current VWAP, and even charts a VWAP-over-time line on the same graph as a price-over-time line. I think this is right along the same lines as what you're looking to do.


Tag Related Posts

CLINQ v1.1.0.0 Released!

Fri 02 May 08 5:38 P GMT-05
tags:          

LINQ to REST - A much better name for Astoria

Tue 11 Dec 07 1:23 P GMT-05
tags:        

Unexpected and Unsafe behavior in LINQ

Wed 14 Nov 07 8:09 P GMT-05
tags:    

Continuous LINQ - Can I write games with it?

Mon 13 Aug 07 3:09 P GMT-05
tags:        

Continuous LINQ

Mon 06 Aug 07 1:21 P GMT-05
tags:    

Dynamic, Observable LINQ Views

Tue 31 Jul 07 1:21 A GMT-05
tags:        

Installing Orcas Beta 1 - VMware Style

Mon 23 Apr 07 12:16 P GMT-05

Visual Studio "Orcas" - March CTP is Available

Wed 28 Feb 07 12:28 P GMT-05
tags:            

Objective-C Categories vs C# 3.5 Language Extensions

Mon 26 Feb 07 1:05 P GMT-05
tags:                

The Latte Effect

Thu 21 Dec 06 7:29 P GMT-05

DLinq vs the ADO.NET Entity Framework

Fri 23 Jun 06 4:01 P GMT-05

WPF/XAML and LINQ - A match made in heaven

Tue 06 Jun 06 11:32 A GMT-05
tags:                  

Language Extensions in C# 3.0

Wed 31 May 06 2:17 P GMT-05

Lambda Lambda Lambda

Sun 21 May 06 1:01 A GMT-05

The Adventures of LINQ (Not Zelda)

Fri 19 May 06 11:21 P GMT-05
tags: