Sunday, March 1, 2009

Going forward with PHP

I run a number of websites which provide a daily update of a shareprice together with the value of the shareprice converted to a loical currency (e.g. £, $, Aus$). When I started, I selected Perl as my scripting language which provided me the necessary facilities (the LWP package) to retrieve a shareprice from the Yahoo finance site. I used the URL
http://finance.yahoo.com/d/quotes.csv?f=l1d2c1p2&s='.$stock_symbol
as my data page which returned the share's closing price and other useful information.

I also generated a graph which showed the historical share price, relative to one of the major indices (e.g. FTSE, CAC40).

As I couldn't host my scripts on my web site, I was required to run a number of Perl scripts to generate updated files and then upload the files to the webhost. I wrapped the scripts in a DOS batch file and set up a scheduled task (under Windows) to run the scripts every weekday after the markets had closed.

This worked very well, most of the time. However it suffered from a number of problems. If I wasn't around, and didn't turn my PC on, then the scripts didn't run and the shareprice wasn't updated. I also suffered from some problems with my web connection which meant that the scripts didn't run as expected and I obtained a zero shareprice.

I had been wondering how to make the system better and less dependent on my PC being turned on. Most ISPs that I have experienced don't allow the LWP package to be installed as part of the standard Perl installation, presumably based on security concerns. I therefore considered alternative scripting languages. I had already seen Python at SPA2008 and was keen to try and see Python was a suitable replacement. However, my web host didn't offer Python in its standard configuration, but did offer the other P language, PHP. 

PHP treats a URL as a filename and does not appear (in the standard configurations installed on webhosts) to suffer from the security constaints that Perl installations suffer. A simple function retrieves the values for a stock symbol returning the parameters in an array.
function get_share_price($stock_symbol)
{
$url="http://finance.yahoo.com/d/quotes.csv?f=l1t1d1c1p&s=".$stock_symbol;
$filesize = 2000;
$handle = fopen($url, "r");
$arr = fgetcsv($handle , $filesize , ',');
fclose($handle);
return $arr;
}
This resolved the problem of updating a daily share price, and also offered the opportunity for offering live share price updates (subject to the market delays which free services such as Yahoo suffer - at  least 15 minutes delay).

To resolve the historic share price required PHP again but this time with a different Yahoo feed which I had only recently discovered, the ichart interface which returns the data as a stream of  CSV separated values. 

function plot($numdays, $stock_symbol)
{
// Get current date
list($e,$d,$f)=split('-',date("j-n-Y"));
$d--; // Months are 0-11
$yahoostr="http://ichart.yahoo.com/table.csv?s=".$stock_symbol."&a=0&b=1&c=2003&d=".$d."&e=".$e."&f=".$f."&g=d&ignore=.csv";
$arrResult = array();
$min=1000;
$max=0;
$handle = fopen($yahoostr, "r");
if( $handle ) 
{
$n=0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
{
if ($n == 0)
{
$n=1; // Ignore header row
}
else
{
$arrResult[] = $data;
}
}
fclose($handle);
// Select data subset
$arr1=array_slice($arrResult,0,$numdays);
// Determine chart scale
foreach ($arr1 as $data ) 
$min = min($data[4], $min); 
$max = max($data[4], $max); 
// Data is currently stored Newest-> Oldest.
$arr = array_reverse($arr1);
// Now plot data (date in element 0, value in element 4).
}
}

In processing the data, I discovered a number of additional PHP features, including
  • array_reverse -to reverse an array (required because the Yahoo data is returned with the most recent data first)
  • array_slice -to take a subset of an array
  • min, max - to determine the minimum and maximum values (how many times has code for this suimple function been written!)
This meant that I had the data in a format which I could then process to produce a graph (dynamically). Now the next question was to select a suitable graphing package which offered a good PHP interface. But that is another story.

No comments: