Disclaimer
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.Introduction
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 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
Here is the code for DataMachine type
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("""http://www.google.com/finance/info?q=""")
urlBuilder.Append symbol
let url = urlBuilder.ToString()
let client = new WebClient()
let cancelToken = Task.Factory.CancellationToken
client.BaseAddress = url
let task() =
try
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
finally
ignore
Task.Factory.StartNew task
let a = new Action(fun () -> (cancelled := true))
a |> Disposable.Create
Observable.Create(operation)
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
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!
Happy coding!