Downloading stock prices in F# – Part I – Data modeling

Other parts:

Today we shipped the September CTP of F# !!!! Evviva !! Read this blog post about it. To celebrate I decided to share one of my several F# project. It might make for a good sample; sort of a crash course on F#.

This application downloads stock prices, dividends and splits from Yahoo Historical Prices and performs computations on them. I will describe it file by file.


I always have such a file in my projects. It is a repository for the types that I’m going to use in my program and the functions that are common across multiple modules. If I have a large program I also have a types.fs just for the types.

This one starts like this:


[<Measure>] type money
let money (f:float) = f * 1.<money>
[<Measure>] type shares
let shares (f:float) = f * 1.<shares>
[<Measure>] type volume
let volume (f:float) = f * 1.<volume>
[<Measure>] type rateOfReturn
let rateOfReturn (f:float) = f * 1.<rateOfReturn>

The first line instructs the compiler to use the lightweight syntax. You don’t want to know what the heavyweight syntax is. Just always put such a line at the start of your files. The next line opens up the System namespace. Then the good stuff starts.

I’m defining some units of measures. The simplest way to think about units of measures is: they are a type system for floats. You can do much more than that, but it is a good first approximation. For example, you cannot now sum a money type and a volume type. Also for each one I define a function that converts from a normal float type to it (if you come from a C# background, floats are doubles).

Then I define the data model for my application:

type Span = { Start: DateTime; End: DateTime }
type Price = { Open: float<money>; High: float<money>; Low:float<money>;
Close:float<money>; Volume: float<volume>}
type Event =
| Price of Price
| Split of float
| Div of float<money>
type Observation = { Date: DateTime; Event: Event}

The first record that I define, Span,  represents the difference between two dates. It is just a little useful thing. A more fundamental record is Observation. An Observation is defined as something that happens on a particular Date. That something, an Event, can be one of three things: a Price, a Split or a Div. A Price is another record with a bunch of float<money> fields and on float<volume> field. If you go to the Yahoo site, you’ll see what it represents.

A Split is simply a float. Why not a float<…>? Because it is just a number, a factor to be precise. It represents the number of new shares divided by the number of old shares. float<shares> / float<shares> = float. A Div is a float<money>.

This is one way to model the problem. Infinite other ways are possible (and I tried many of them in a C# version of this code that ended up using polymorphism). Note that all of the types are records except Event that is a discriminated union.

Records are read only containers of data. Discriminated unions are what the name says: things that can be one of multiple things (even recursively). They are rather handy to represent the structure of the data. We will see how you use them using the match operator in upcoming posts.

Also notice the following common pattern in F# (and functional programming in general). You define your data and then you define transformations over it. F# has a third optional step, that is to expose these transformations as methods of a .NET objects.

We are almost done here. A handful of other functions are in my file :

let span sy sm sd ey em ed =
{Start = new DateTime(sy, sm, sd); End = new DateTime(ey, em, ed)}
let date y m d = new DateTime(y, m, d)
let now () = DateTime.Now

let idem x = x
let someIdem x = Some(x)

Span is a function that creates a span given the relevant info. date creates a date given year, month and day. now is a value that corresponds to the current date. idem is a function that returns its parameter (you’ll see how that can possibly be useful). someIdem is a function that unpack an Option type and gives his value. I could write all my code without these things, but it looks better (to me) with them.

Notice that in the F# code you have access to all the functions and type in the .NET framework. It is just another .NET language: it can create or consume .NET types.

All right, we are done for part one. In part II there will be some real code.