Inspired by Dave Thomas’ “A First Erlang” post I decided to use Erlang to retrieve stock quotes from Google’s Finance API. I wrote a simple Erlang program that let me explore third party JSON libraries and Erlang’s http library.
In Erlang, the -module directive defines an Erlang module, which is how code is organized in Erlang, the -export directive tells Erlang which functions in this module to expose. My Erlang module is called quote, and I’m storing it in the file quote.erl. I’m also exposing a single function get_stock_quote which accepts a single parameter.
-module(quote). -export([get_stock_quote/1]).
Next I’ll define an Erlang macro called BASE_URL which contains the base URL of the Google Finance API. The function get_google_url builds the full URL by appending the symbol to the base URL.
-define(BASE_URL, "http://www.google.com/finance/info?client=ig&q=". get_google_url(Symbol) -> ?BASE_URL ++ Symbol.
After retrieving a stock quote for MSFT in our browser I noticed that the data returned from Google Finance is a JSON(ish) object surrounded by some extraneous text which has to be removed before we can do anything else. Later I’ll use an external library to convert the string into a JSON object and extract the price and date.
get_stock_quote(Symbol) ->
%% Don't know why I need the following line
%% mentioned in inets documentation
inets:start(),
URL = get_google_url(Symbol),
{ ok, {_Status, _Headers, Body }} = http:request(URL),
PureData = lists:subtract(lists:subtract(Body, "// [ "), "] ").
The code to make http request is simple, http:request() returns the HTTP status, headers and body but the call was throwing an exception on my machine; after reading the http documentation included with Erlang I learned that a call inets:start() has to be made before making a http request. The variable PureData contains the string which will transform into our JSON object, I had to use the lists:subtract function to remove extra characters from the beginning and end of the string.
After some searching (and cursing) I found a third party library, json_parser, on Process One’s Comprehensive Erlang Archive Network. I downloaded a copy of the development version, renamed the source file to json_parser.erl, compiled json_praser and referenced it from quotes.erl with the -import(json_parser) import directive.
The documentation for json_parser is fairly sparse—the dvm_parser function in the library returns a tuple with more data then I need and I’m only interested in the actual JSON data which I’ parsed into the RealData variable and passed onto the parse_json_tuple function which extracts the fields I’m interested in.
{_,{_,RealData},_} = json_parser:dvm_parser(list_to_binary(PureData)),
parse_json_tuple(list_to_tuple(RealData)).
Finally, I parse the data in the RealData tuple and returned the CurrentPrice and Quote time:
parse_json_tuple(RealData) ->
%% this is ugly and needs to be refactored
{_,_,_,_,{_,CurrentPrice},_,{_,CurrentTime},_,_,_} = RealData,
{CurrentPrice, CurrentTime}.
To use the code, you have to compile the quote.erl file by calling the c(quote) function in the Erlang Shell, then call the get_stock_quote function with the a stock symbol: quote:get_stock_quote(“MSFT”) from the Erlang shell.
This isn’t the best use of Erlang, but I wanted to ease into Erlang before exploring the more complicated recursive and distributed functionality, later I’ll refactor the code to be more Erlang-y and modify the program to retrieve quotes in parallel using Erlang’s concurrency magic.
*Edit*I Just discovered that Google Finance returns a slightly different dataset when the market is closed, I’ll update the parse_json_tuple function with the changes soon.
Full Listing
1: -module(quote).
2: -export([get_stock_quote/1]).
3: -import(json_parser).
4:
5: -define(BASE_URL, "http://www.google.com/finance/info?client=ig&q=".
6:
7: get_google_url(Symbol) ->
8: ?BASE_URL ++ Symbol.
9:
10: parse_json_tuple(RealData) ->
11: %% this is ugly and needs to be refactored
12: {_,_,_,_,{_,CurrentPrice},_,{_,CurrentTime},_,_,_} = RealData,
13: {CurrentPrice, CurrentTime}.
14:
15: get_stock_quote(Symbol) ->
16: %% Don't know why I need the following line
17: %% mentioned in inets documentation
18: inets:start(),
19: URL = get_google_url(Symbol),
20: { ok, {_Status, _Headers, Body }} = http:request(URL),
21: PureData = lists:subtract(lists:subtract(Body, "// [ "), "] "),
22: {_,{_,RealData},_} = json_parser:dvm_parser(list_to_binary(PureData)),
23: parse_json_tuple(list_to_tuple(RealData)).
Related posts:





[...] main strength is its support for concurrency– now I’ll extend the previous Erlang example to fetch the stock quotes for multiple symbols in [...]
Shey’s Rebellion :: More Erlang: Adding Concurrency - 6 Apr 09 at 11:36 pm
Hi,
I’m trying to fetch google realtime data via php from google finance.
Sadly it’s not possible via php as far as I can tell because google finance consists out of java. Could you tell me a way to do this? If you know one of course^^.
Greetings soeren
Soeren - 9 Sep 09 at 2:52 am
you can do same using PHP also
Do something like this:
Once you have this data you can parse this JSON using javascript or even php also.
For more information check my blog http://www.intellitures.com/blog/?p=189
Intellitures - 19 Nov 09 at 1:42 am
I missed code in last reply
<?php require(“http://www.google.com/finance/info?client=ig&q=GOOG”); ?>
you can use this to create your own proxy.
Intellitures - 19 Nov 09 at 1:44 am
ohh yeah, it’s definitely much simpler in PHP, Ruby, Python…etc. It was simply an exercise in Erlang
Shey - 25 Nov 09 at 6:23 pm
Beautiful snippet. Now I can (finally) fetch data from any server with Erlang. Thank you!
Arthur Buliva - 20 Apr 10 at 7:49 am
My name is Hellen. I’m from U.S. I like chatting on video. If you have a good personality and if you are between 18-35yrs please visit http://sexporn123.info/pic/girl15.php, see my photo , and I video chat. I am so lonely and need some fun with confident guy.
Goolypewore - 30 Apr 11 at 8:36 pm
Useful info. Fortunate me I discovered your website accidentally, and I’m shocked why this coincidence did not happened in advance! I bookmarked it.
Dating Secrets - 28 May 11 at 2:04 am
Well, such a wonderfull experience its been dropping by a blog like this. So I thought I would make a post. It was recommended to me so I thought I’d get myself over here & check it over and yes, I agree… great work. There are so many blogs on the net that are just plain boring & it’s cetainly terrific to see someone telling it like it is, keep it up.
Reiko Dsouza - 21 Jun 11 at 10:47 pm
Fantastic goods from you, man. I’ve understand your stuff previous to and you are just extremely great. I really like what you’ve acquired here, really like what you are saying and the way in which you say it. You make it entertaining and you still take care of to keep it wise. I can’t wait to read far more from you. This is really a tremendous web site.
Inteligentny Dom - 16 Oct 11 at 9:57 am
would people choose barak? be honest
% - 26 Nov 11 at 5:26 am
Hi there, I found your website by the use of Google whilst looking for a comparable topic, your site came up, it seems to be great. I have added to favourites|added to bookmarks.
personal finance tips - 14 Dec 11 at 6:47 pm
This is very true.I lost my weight just made changes in food ,taking all vegetarian and of low carb http://www.sheysrebellion.net helped me a lot and I suggest everyone
winstrol - 18 Dec 11 at 1:15 am
I cannot thank you enough for the articles on your website. I know you put a lot of time and energy into them and hope you know how considerably I appreciate it. I hope I can do something identical for another individual sooner or later.
Swtor Guides - 22 Jan 12 at 11:21 pm