2009
Working at WallSt I’ve delt with numerous data providers for our financial information. Data feeds are not cheap especially when you have to deal with individual exchange fees. Often times when selecting a provider you are limited by their charts and graphs. You can usually get ticker information in XML, but graphical data is usually restricted to modules or API calls for an image.
One solution is to obtain a historical feed and develop a charting system, but this can be expensive and time consuming. So how can we do this cost effectively and quickly?
Thank you Yahoo. Yahoo provides historical quotes in spreadsheet (CSV – comma separated values) format which can be easily parsed. I have no idea how they can provide this freely. But I won’t question it
. Looking at this service, I see that it has changed many times and there are / has been various methods for obtaining their CSV data. So that’s a word for caution should anything change in the future.
Step 1. How to obtain historical quotes:
You can get the data by using the URL below.
http://ichart.finance.yahoo.com/table.csv?s=YHOO
This will provide you with all the EOD price of a company since its IPO. The method above uses the CSV output on a webpage. Yahoo has other URLs that output a downloadable files. Those work also and can be parsed just as easily.
If you want to be able to select a specific date range you can do it in this format:
http://ichart.finance.yahoo.com/table.csv?s=YHOO&a=0&b=1&c=2008&d=11&e=31&f=2008&g=d
Here I’m selecting data just for the year 2008 from 01/01/08 – 12/31/08.
Let’s break down the URL string and take a look at each parameter.
s = The requested ticker symbol.
a = The starting month in two digit format. (ie: “00″ = January, “01″ = February, etc.)
b = The starting day. (ie: 1, 2, … 30, 31)
c = The starting year in four digit format (ie: “2000″)
d = The ending month in two digit format. (ie: “00″ = January, “01″ = February, etc.)
e = The ending day. (ie: 1, 2, … 30, 31)
f = The ending year in four digit format (ie: “2000″)
g = The data interval (ie: “d” = daily, “w” = weekly, ‘m’ = monthly. The default is ‘daily’ if you ignore this parameter.)
Step 2. Retrieving and Parsing the Data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <? //////////////////////////////////////////////////////////////// // data.php // // This file will dynamiclly output the CSV locally on your // server to overcome the security restriction in Flash . //////////////////////////////////////////////////////////////// function ScrapePage ($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $fileoutput = curl_exec($ch); curl_close($ch); return $fileoutput; } $symbol = $_REQUEST["symbol"]; $output = ScrapePage("http://ichart.finance.yahoo.com/table.csv?s=".$symbol); $output = str_replace("Date,Open,High,Low,Close,Volume,Adj Close\n", "", $output); echo $output; ?> |
I’m using a simple curl function to get the page. Fopen, wget or whatever your weapon of choice should work too. Since we only need the data, I’m removing the column header with a str_replace. The graphing method I will use will take the data in this format so there will be no parsing or manipulating invovlved. That’s all we need to do for this part.
Step 3. Graphing the Data
Building a full fledge charting system in Flash is quite a bit of work. Adobe has simplified this with Flex, which has built in charting support. It’s a great way to go if you have the knowledge and resources to build some very customized. But I’m gonna take this a few more steps down easy street and use a pre compiled flash suite to do the charting.
I will be using charts from amCharts.com. Not just because its free and easy, these are some really well made charts and they look really good. They have a variety of chart types.
Their stock suite can be downloaded here: http://www.amcharts.com/download
I will be using the event chart type in this example. I picked this one because it is the most familiar layout for stocks. It has the standard line chart but also includes the ability to add events. Which for a stock chart, you can labels for news, splits, dividends, etc.
From the download we will need the following files:
/amstock/amstock.swf – The flash file that displays the graph.
/amstock/swfobject.js – Standard flash embed file.
/examples/events/amstock/amstock_setting.xml – The settings file with output parameters
data.php – This is the file we created above.
Once you have all the files, place them in the same directory. Now we’ll edit the files.
First we’ll modify the amstock_setting.xml file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | <php //////////////////////////////////////////////////////////////// // settings.php // // This file is based amstock_setting.xml (event chart type). // I've done a bit of editing to clean up the number display // and added some sample events. // // I've also converted it to php so we can dynamiclly pass // the ticker symbol. //////////////////////////////////////////////////////////////// ?> <?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?> <!-- Only the settings with values not equal to defaults are in this file. If you want to see the full list of available settings, check the amstock_settings.xml file in the amstock folder. --> <settings> <margins>0</margins> <redraw>true</redraw> <number_format> <separator>,</separator> <decimal_separator>.</decimal_separator> <thousand_separator>,</thousand_separator> <letters> <letter number="1000">K</letter> <letter number="1000000">M</letter> <letter number="1000000000">B</letter> </letters> </number_format> <data_sets> <data_set did="0"> <title>East Stock</title> <short>ES</short> <color>7f8da9</color> <file_name>/post-content/flashchart/data.php?symbol=<?php echo $_POST["symbol"]; ?></file_name> <csv> <reverse>true</reverse> <date_format>YYYY-MM-DD</date_format> <separator>,</separator> <decimal_separator>.</decimal_separator> <columns> <column>date</column> <column>open</column> <column>high</column> <column>low</column> <column>close</column> <column>volume</column> <column>adj close</column> </columns> </csv> <events> <event> <date>2007-12-25</date> <letter>A</letter> <description><![CDATA[Christmas Day]]></description> </event> <event> <date>2008-01-01</date> <letter>B</letter> <description><![CDATA[New Years Day]]></description> </event> <event> <date>2008-12-25</date> <letter>C</letter> <description><![CDATA[Christmas Day]]></description> </event> <event> <date>2009-01-01</date> <letter>D</letter> <description><![CDATA[New Years Day]]></description> </event> <event> <chart_id>second</chart_id> <graph_id>volume</graph_id> <date>2004-05-12</date> <bullet>pin</bullet> <description><![CDATA[Split 2:1]]></description> <axis>true</axis> <size>12</size> </event> <event> <chart_id>second</chart_id> <graph_id>volume</graph_id> <date>2009-03-19</date> <bullet>pin</bullet> <description><![CDATA[Fake Dividends]]></description> <axis>true</axis> <size>12</size> </event> </events> </data_set> </data_sets> <charts> <chart cid="first"> <height>60</height> <title></title> <border_color>#CCCCCC</border_color> <border_alpha>100</border_alpha> <values> <x> <bg_color>EEEEEE</bg_color> </x> </values> <legend> <show_date>true</show_date> </legend> <column_width>100</column_width> <events> <color>fac622</color> </events> <graphs> <graph gid="close"> <data_sources> <close>close</close> <high>high</high> <low>low</low> </data_sources> <bullet>round_outline</bullet> <legend> <date key="false" title="false"><![CDATA[<b>Price:</b> {close} <b>High: </b>{high} <b>Low: </b>{low}]]></date> <period key="false" title="false"><![CDATA[<b>Price:</b> {close} <b>High: </b>{high} <b>Low: </b>{low}]]></period> </legend> </graph> </graphs> </chart> <chart cid="second"> <height>30</height> <title></title> <border_color>#CCCCCC</border_color> <border_alpha>100</border_alpha> <grid> <y_left> <approx_count>3</approx_count> </y_left> </grid> <values> <x> <enabled>false</enabled> </x> </values> <legend> <show_date>true</show_date> </legend> <column_width>0</column_width> <events> <color>db4c3c</color> </events> <graphs> <graph gid="volume"> <type>column</type> <data_sources> <close>volume</close> </data_sources> <period_value>average</period_value> <alpha>100</alpha> <fill_alpha>0</fill_alpha> <legend> <date key="false" title="false"><![CDATA[<b>Volume:</b> {close}]]></date> <period key="false" title="false"><![CDATA[<b>Volume:</b> {close}]]></period> </legend> </graph> </graphs> </chart> </charts> <date_formats> <events>DD month YYYY</events> </date_formats> <data_set_selector> <enabled>false</enabled> </data_set_selector> <period_selector> <periods> <period type="DD" count="10">10D</period> <period type="MM" count="1">1M</period> <period type="MM" count="3">3M</period> <period selected="true" type="YYYY" count="1">1Y</period> <period type="YTD" count="0">YTD</period> <period type="MAX">MAX</period> </periods> <periods_title>Zoom:</periods_title> <custom_period_title>Custom period:</custom_period_title> </period_selector> <header> <enabled>false</enabled> </header> <scroller> <graph_data_source>close</graph_data_source> <resize_button_style>dragger</resize_button_style> <playback> <enabled>true</enabled> <speed>3</speed> </playback> </scroller> </settings> |
What I did here was cleaned up some of the XML and added some sample events. I’ve also changed the extension to php since we will be dynamically passing the ticker symbol to the data.php file.
Next we put everything together to display the graph:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <? //////////////////////////////////////////////////////////////// // index.php // // Displays the graph and takes a requested symbol //////////////////////////////////////////////////////////////// ?> <?php $symbol = $_REQUEST["symbol"]; if (!$symbol) { // if no symbol is inputted defaults to yahoo $symbol = "YHOO"; } ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Flash Chart</title> </head> <body bgcolor="#FFFFFF"> <!-- saved from url=(0013)about:internet --> <!-- amstock script--> <script type="text/javascript" src="swfobject.js"></script> <div id="flashcontent"> <strong>You need to upgrade your Flash Player</strong> </div> <script type="text/javascript"> // <![CDATA[ var so = new SWFObject("amstock.swf", "amstock", "550", "300", "8", "#FFFFFF"); so.addVariable("path", ""); so.addVariable("settings_file", encodeURIComponent("settings.php?symbol=<?php echo $symbol; ?>")); so.write("flashcontent"); // ]]> </script> <!-- end of amstock script --> <br> <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> Enter Symbol: <input name="symbol" type="text" value="<?php echo $symbol; ?>" /> <input name="submit" type="submit" value="Go" /> </form> </body> </html> |
The form passes our ticker symbol to the setting file which will dynamiclly call the data file with the appropriate symbol.
So there you have it…a nice looking flash graph with historical data. I’ve left out some error checking for the bare minimum to get this done. You can use this technique for other series data. There is one hiccup to all this. It lacks intraday data. That’s pretty vital information when dealing with stock price. However its just a matter of obtaining a feed. Unfortunately, I haven’t been able to find a free source for this data. This would surely seal the deal in creating a no cost flash stock chart that would rival Yahoo and Google.

Hi Poli, very good article – I just thought I mentioned a little imprecision. In Yahoo url string both months parameters ‘a’ and ‘d’ take the value of ’0′ for the first month (January).
Bests
Enrico
Thanks for the correction =). It is now fixed in the article.
Hi there.
It all look very very nice. I am trying to add it to my website. Its a wordpress site… so far I didn’t manage to do so…
I followed your instructions, but it didn’t work out. I also tried to just generate a normal html site but it didn’t work. It says the settings.php is missing… any suggesitons what i could do?
regards
Hannes
Hi Hannes,
WordPress can be a bit tricky if you are inserting it into a post or page. You will have to use a plugin that will allow you to execute PHP code. You’re on the right track with making a html site. Its easier to see if you have that working first. If you have files in different directories, place them in the same place as flash doesn’t like to load files (setting.php) that are not in the same location as the swf file. Once you have it working on a stand alone page, you can use some different options to put it into WordPress like an iframe or ajax if you want to avoid executing php code in your post.
Hi Poli,
I’m getting “operations aborted” error in ie7, though it works in opera and firefox.
Can you pls guide where the problem might be?
regards
Sunny
Hi,
this is fantastic and I have managed to get it to work (almost) perfectly in wordpress.
Really good !
I only have a couple of questions, is it possible to make this work with the OHLC and Candlestick as well. Has this code something to do with it ?
line
close
high
low
Also, for some reason I get a lot of padding above the chart and some below, do you know why this happens ? It only seems to happen with amcharts, embedded video and other media works fine.
It would be much appreciated if you could help me !
Thanks and keep up the awesome work !
KM
Oh, and also, if I load the chart in a “page” in wordpress and change the ticker, the page reloads back to the root URL !?
If I load the chart in the root URL it works fine..
eg when I change the ticker in the amchart on this page
http://www.myhomepage.com/?page_id=73
it reloads to
http://www.myhomepage.com
but if I post it on http://www.myhomepage.com
it works fine.
and so it is impossible to change the ticker from a page.
Can this be easily changed?
Thanks again,
KM
Hi KM,
I haven’t looked into OHLC or candlestick, but I’m sure it would follow the same principle. You will need a data source that will give you all the extra data needed to chart those details such as the days high/low range, open/closing price and direction. I’m not sure if there is a CSV feed from yahoo that offers all that data. You will also need a flash graph that can take all those data points. If you can obtain both, the coding is essentially the same. So its not really a code limitation, more of a data source and output format issue.
As for the extra padding, its probably an embedding or html issue. Try removing any extra spaces or returns. Maybe try playing around by wrapping some div around it to get some hints where the extra padding is coming from. Also, right click in the padded area and see if the flash menu pops up. If it doesn’t then its definately an html issue. If it the flash menu does pop up, then the padding is inside the flash object itself so check the sizes when you’re embedding the graph.
Lastly, it depends on how you embedded the graph to get the ticker to change properly. If you use an iframe as I did in my example then the frame will just reload itself and you don’t have to worry about wordpress. But if you embedded directly in a wordpress page, then make sure the form post back to your page (ie:http://www.myhomepage.com/?page_id=73). And on that page you’ll have to request the post variable and pass it as a querystring to the settings.php file when you’re embedding the flash script.
Hi Poli,
thank you for your help. I followed your ideas and found out that the problem was with the WUSIWUG editor in wordpress – it automatically ads tags around php script… The problem is apparently well known and a plugin disableautop can be installed that removes the automatic tags. However this means I have to add these tags in other posts to get linespacing – nevermind – it’s a quick fix.
With regards to the refresh issue I have not solved it. The problem is that I have very little experience with coding. If you could have a look at http://www.globalmacroblog.com/?page_id=73 and give me some ideas about how to solve this it would be extremely kind of you.
Thank you again for your help and your fantastic solution for combining free Yahoo feed and amCharts !
KM
KM, nice implementation of the graph.
First thing you want to do is change
<form method=”post” action=”/index.php”>
to
<form method=”post” action=”http://www.globalmacroblog.com/?page_id=73″>
and then change
so.addVariable(“settings_file”, encodeURIComponent(“../amstock/settings.php?symbol=UNG”));
to
so.addVariable(“settings_file”, encodeURIComponent(“../amstock/settings.php?symbol=< ?php echo $_POST["symbol"]; ?>“));
What this is doing is telling the form to send the symbol back to the graph page and not the wordpress homepage. The second part passes the symbol to the flash graph embedded on that page.
Hi, I tried your suggestion but it did not seem to work.
I guess you found this: in the source code, but I actually use the same code as you have on this page: <form method="post" action="”>
Never mind, amCharts very kindly wrote a code which works as long as I click the go button. If I press enter it still refresh back to the root site !?
Wrt more than EOD Line charts, Yahoo already provide OHLC data in the file we download: http://ichart.finance.yahoo.com/table.csv?s=YHOO
And amCharts already have a function to chart both candlestick and OHLC bars:
http://www.amcharts.com/stock/ohlc-chart/
I have basically been on the lookout for what you have now created for 10years.
There really is no other solution to get free data in a slick interface on your own site.
I believe there are very serious commercial opportunities in developing further what you have started, but with a bit more functions.
If such a site would also offer futures and options feed in the same interface, it would be the first I know of on the web.
RT feed would be for paying members only…
I believe the closest competitor would be this relic, and there is no way to use their charts on your own site:
(http://charts3.barchart.com/chart.asp?sym=c&data=A&jav=adv&vol=Y&divd=Y&evnt=adv&grid=Y&code=BSTK&org=stk&fix=)
Just a thought .. !
KM
Hi KM, glad to see the charts are working well enough for you now. I do agree with you on the commercial potential of a more robust tool. I’ve been working with financial feeds for 5 years and this is the only “cheap” solution I’ve been able to implement. Data feeds and development time is very costly if someone wanted to create something from scratch.
Thanks for the heads up on the OHLC data, it should come in handy for candlestick graphs. I may do something with it in the future.
Let me know if you have more questions.
heelo i try to make this script
i i have a error..
error loading faile
http://ichart.finance.yahoo.com/table.csv?s=goog
???
thanks
i think that my problem is about cross domains, or directory whith paths, can you put a download file please thanks.
Hi. Thanks for the tutorial.
But it is not working for me either.
First i had to change on settings.php
to
And then i have this error:
Error loading file: /post-content/flashchart/data.php?symbol=YHOO
If you can help.
Thanks.
It wont show tags. I changed from post to get on settings.php
BTW i have all files in the same folder.
amstock.swf
data.php
index.php
swfobject.js
settings.php
Really nice tutorial, thanks for the effort!
Jani.
http://www.origofx.com
hi thanks
ive followed your instructions and i get the
flash but the data is missing
i get a ” date format error
your advise
Its easier to see if you have that working first. If you have files in different directories, place them in the same place as flash doesn’t like to load files (setting.php) that are not in the same location as the swf file