Thursday, June 26, 2014

F# example: Getting live stock ticks through Google Finance API

NOTE: This article demonstrates how F# in conjunction with Reactive Extensions can be used to connect to live data streaming. The full project with example client can be found at This Github link.


I do not  take any responsibility of the code and any damages caused by it. Code which is provided AS IS is only for demonstration purposes and in no way encourages anyone to use Google Finance API for business. 


It has been a week learning F# and I have finally converted my C# code that uses Google Finance API to F#

Here is what my code does. In simple words, it gives you back the IObservable<Tick> for one security (or symbol)

Here is the screenshot of how it looks like

Here is how you use it as a library in C#
 DataMachine machine = new DataMachine();  
 IObservable<Tick> appleTicker = machine.GetStockQuote("AAPL"); // Get Apple's stock prices  
 appleTicker.Subscribe(tick => {  
        // Everytime price changes, this piece of code will be called and an   
       // An object of Tick will be supplied as tick  
       // You can either add them to your Graph series to plot live chart  
       // Or save them to CSV  

Google Finance API

The simple finance API by Google is just a URL that takes symbol in 'q' GET parameter (or query string parameter). The following will give you the current price data for Yahoo in Json format.

How it works ?

It creates a thread using TaskFactory which queries Google Finance every 1 second, fetches the price and if there is a change in price produces the output into the Observable. Google Finance API gives back Json object. I am using Json.Net library by James-Newton King to parse that.

Here is the type definition of Tick
 type Tick() =   
     [<JsonProperty(PropertyName = "t")>]   
     member val Symbol = Unchecked.defaultof<string> with get, set  
     [<JsonProperty(PropertyName = "l")>]  
     member val Price = Unchecked.defaultof<float> with get, set  
     [<JsonProperty(PropertyName = "lt_dts")>]  
     member val LastUpdated = Unchecked.defaultof<DateTime> with 

Here is the code for DataMachine type
 type DataMachine() =   
   member this.GetLiveGoogleApiTicks(symbol : string) =  
     //google_api queries Google APi every second and produces the string output  
     let google_api (symbol : string) =  
       // When operation is cancelled by the caller, this variable will be modified  
       let cancelled = ref false  
       let operation(o : IObserver<string>) =  
         //Time to wait before fetching again through the API  
         let timeToSleep = TimeSpan.FromSeconds(1.0)  
         //Google Finance API , notice q is the query string parameter for symbol  
         let urlBuilder = new StringBuilder("""""")  
         urlBuilder.Append symbol  
         let url = urlBuilder.ToString()  
         let client = new WebClient()  
         let cancelToken = Task.Factory.CancellationToken  
         client.BaseAddress = url  
         let task() =  
                 while not cancelToken.IsCancellationRequested && not !cancelled do  
                   let data = client.DownloadString url  
                   //Produce the item in observable  
                   o.OnNext data  
                   Thread.Sleep timeToSleep  
                   while client.IsBusy do  
                     Thread.Sleep 100  
         Task.Factory.StartNew task       
         let a = new Action(fun () -> (cancelled := true))  
         a |> Disposable.Create  
     let strings = (google_api symbol)  
     // Eliminate unparseable characters for Json.Net library  
     let trimmed = strings.Select (fun (l:string) -> l.Substring(l.IndexOf("[") + 1, l.LastIndexOf("]") - 2 - l.IndexOf("[") + 1))  
     //Parse into object and return the IObservable<Tick>  
     trimmed.Select(fun (l:string) -> JsonConvert.DeserializeObject(l)).DistinctUntilChanged(fun (a:Tick) -> a.Price)

Remember to add Rx-Main and Json.Net from Nuget in your project and add appropriate 'open' declarations for namespaces.

Download the code

The fully functional project with sample client for this project can be found at This Github link.

Let me know your comments in the section below. If there is anything that I should have done differently, I would love to hear about that.

Happy coding!