as guid, even if the guid is there, making it impossible to get it to update, even if the guid changes. Remove the link to solv problem. default=yes randomlink=yes, added a random part to the link, in the attempt of fooling the rss reader to think that it's a new item. Default=no onlytotal=yes, only create the total item. Default no. graph=[yes,1ds,1d,5d,3m,6m,1y,2y,5y,my] adds one or more links to graphs displaying [1 day small, 1 day, 5 day, 3 month, 6 month, 1 year, 2 year, 5 year or max year].It's possible to specify more that on graph by seperating them with comma or +: graph=1d+1y for the 1 day and 1 year graphs. The old option "yes" will display the 1ds (1 Day Small) graph fulltitle=yes uses the full title of the company if possible. Defalut no. titlenoshort=no forces fulltitle=yes and only uses the fulltitle on the headlines (makes them a bit shorter). titlenovalue=no removed the day value from the title titlenochange=no removed the day change value from the title Version history: 2005-11-23 - 0.0.8: * Added multi graph options as suggested and researched by "ttys0", this uses the bigger graphs that yahoo supplies * you can now split symbols by either , or + * max number of symbols is now 20 * Changed the note 2005-11-09 - 0.0.7: * Fixed the change procentage to be based on aqusition value. * Changed the code that get the fulltitle so that it works with the new yahoo layout. * Fixed it so that values are only added to total if both count and aquire value is given. * updated the header url * added a $noteheader and a $notebody vars to the init part. Write something in the header variable and an extra item will be written with the message. Currently used to warn about the change in diff calculation. * added titlenochange - which will remove the (+.23) part of the title. I really should make at a formatting variable ... 2005-07-27 - 0.0.6: * Added leaching blocker. A file called stock.leach.php is written that contains the unix time (seconds since some data) since that ip address last requested a quote. It is less than 20 minuts an error message is returned, tell people to stop leaching... 2005-01-31 - 0.0.5: * fixed stupid reusage of the $data variable 2005-01-21 - 0.0.4: * fixed version number * added time-to-live ttl 20 minuts metadata * added graph option * added caching of full symbol title (needs write access to server file) * added the fulltitle option * cleaned up the printitem function, made the disclaimer optional * added a bit of sanity check on the symbol size and for unknown symbols 2005-01-15 - 0.0.3: * added information for no parameters * added more meta/header information 2005-01-14 - 0.0.2: * added randomlink option * added onlytotal option * added more information to the total item (so it's useful on its own) * fixed warning at blank title * fixed some division by zero error (don't try to calc values when impossible) 2005-01-13 - 0.0.1: * First version (TC) To-Do list: * The time stuff aren't correct, in the total local server time is used * Some kind of caching might be nice * More options on what to include * Maybe somekind of expire might be a good idea * Make a more flexible title and page formatting system */ $version='0.0.8'; #putenv('TZ='.$_SESSION[PROFILE_TZOFFSET]); $noteheader=''; $notebody='It\' now possible to specify that you want more graphs graph=1d,5d,5y will give you one 1 day, 5 day and 5 year graphs. See the site for more info http://blog.tc.dk/item/8 '; @include('stock.dat.php'); function rssheader() { global $version; if (isset($_GET['title'])) $title=$_GET['title']; else $title='Yahoo Stock To Rss'; print ' '.$title.' http://blog.tc.dk/item/8 http://blogs.law.harvard.edu/tech/rss SaturdaySunday Finance YStockToRSS v'.$version.' tc@tc.dk en-us Stock Ticker and Portfolio Watcher via RSS 20 '; } function rssfooter() { print ''; } function printitem($title, $link='', $desc='no-text', $time='', $guid='', $disclaimer=true) { // prints one item if ($link!='') { if ((isset($_GET['link'])) and ($_GET['link']=='no')) $link=''; else if ((isset($_GET['randomlink'])) and ($_GET['randomlink']=='yes')) $link .= '&random='.rand(1,9999999); } print ''; print ''.$title.''; if ($link!='') print ''.$link.''; if ($guid!='') print ''.$link.''; // print ''.$guid.''; if ($time!='') print ''.date('r',$time).''; print ''.htmlentities($desc); if ($disclaimer) print htmlentities('

Delayed data gathered from finance.yahoo.com.'); print '
'; print "
\n"; } function getyahoostockprice($symbol) { //stock quote script inspired by http://tutorials.programmingsite.co.uk/yahoocsv.php $ch = curl_init(); curl_setopt ($ch, CURLOPT_URL, "http://finance.yahoo.com/d/quotes.csv?s=".$symbol."&f=sl1d1t1c1ohgv&e=.csv"); curl_setopt ($ch, CURLOPT_HEADER, false); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 5); $content = curl_exec($ch); curl_close($ch); $data = array(); $data = explode(",", $content); $data[0] = str_replace("\"", "", $data[0]); $data[2] = str_replace("\"", "", $data[2]); $data[3] = str_replace("\"", "", $data[3]); // data[0]=symbol // data[1]=last price // data[2]=date // data[3]=time // data[4]=change // data[5]=open price // data[6]=day high price // data[7]=day low price // data[8]=trade volume return $data; } function isleach() { $visitorip = $_SERVER['REMOTE_ADDR']; if ($visitorip=='209.217.115.86') return true; else return false; @include('stock.leach.php'); if (isset($lastvisit[$visitorip])) { if ($lastvisit[$visitorip]<(time()-(19*60))) $retval= false; else $retval= true; } else { $retval=false; } $lastvisit[$visitorip]=time(); $wf = fopen('stock.leach.php', 'w'); if ($wf) { // save the last visit times but only if they are from with in the last 24 hours fwrite($wf, " $svalue) if ($svalue>(time()-(24*60*60))) fwrite($wf, ' $lastvisit[\''.$skey.'\']=\''.$svalue.'\';'."\n\r"); fwrite($wf, '?>'); } return $retval; } // main part of code if (isset($_GET['symbols'])) // any parameters we care about? { header('Content-Type: text/xml'); rssheader(); if ($noteheader!='') printitem($noteheader,'http://blog.tc.dk/item/8',$notebody,'','',false); if (isleach()) { printitem('STOP LEACHING','',"You are getting this message because you've requested a stock quote twice within 20 minuts. DON'T DO THAT. There's a TimeToLive 20 minuts in the RSS and if you or your RSS program can't honour that you'll need to run your own server. Oh, and shame on you - somebody goes to a lot of trouble to set up a free service and you abuse it.", '','', false); } else { // initialize and do each symbol $sym = split('[,+ ]', $_GET['symbols'],20); $totaq=0; $totcur=0; $totdif=0; $maxdate=0; $totalstr='SYMBOL: Current - Acquisition = value
'; if ((isset($_GET['fulltitle'])) and ($_GET['fulltitle']=='yes')) $fulltitle=true; else $fulltitle=false; if ((isset($_GET['titlenoshort'])) and ($_GET['titlenoshort']=='yes')) $titlenoshort=true; else $titlenoshort=false; if ($titlenoshort) $fulltitle=true; if ((isset($_GET['titlenovalue'])) and ($_GET['titlenovalue']=='yes')) $titlenovalue=true; else $titlenovalue=false; if ((isset($_GET['titlenochange'])) and ($_GET['titlenochange']=='yes')) $titlenochange=true; else $titlenochange=false; foreach($sym as $key => $value) { $data = split('[:]', $value,3); // Print_r($data); if ((isset($data[0])) and (trim($data[0])!='') and (strlen($data[0])<20)) // do we have a symbol name? { $symbol=$data[0]; $title=''; if ($fulltitle) { if (!isset($symboldata[$symbol])) { $fp = fopen ("http://finance.yahoo.com/q?s=".$symbol,"r"); if ($fp) { $d=''; while (!feof($fp)) { $d .= fread($fp, 8192); } $startstr='('.strtoupper($symbol).')'; $endstr=' ('; $end = strpos($d, $startstr)-1; if ($end>0) { $start=$end; while ((substr($d, $start, 1)!='>') and ($start>0)) // run until we find the first tag $start = $start - 1; $start = $start+1; if (($end-$start)<100) // sanity check $title = substr($d, $start, $end-$start); } } if ($title!='') { $symboldata[$symbol]=$title; $wf = fopen('stock.dat.php', 'w'); if ($wf) { fwrite($wf, " $svalue) fwrite($wf, ' $symboldata[\''.$skey.'\']=\''.$svalue.'\';'."\n\r"); fwrite($wf, '?>'); } } } else { $title = $symboldata[$symbol]; } } if (isset($data[1])) // is there a count of stock? $count=$data[1]; else $count=0; if (isset($data[2])) // is there a cost for the stock? $cost=$data[2]; else $cost=0; $data=getyahoostockprice($symbol); // get from yahoo if ($data[1]>0) { // calc values and totals $aq=($cost*$count); $cur=($data[1]*$count); $dif=($cur-$aq); if (($aq>0) and ($count>0)) { // only update total if we have both aquire and count values $totaq +=$aq; $totcur +=$cur; $totdif +=$dif; } if (($cur>0) and ($aq>0)) $totalstr .= $data[0].':'.$cur.'-'.$aq.'='.$dif.' ('.number_format((($dif/$aq)*100),2).'%)
'; if (isset($_GET['timedif'])) $dat = strtotime($data[2].' '.$data[3]) + $_GET['timedif']*3600; else $dat = strtotime($data[2].' '.$data[3]); if ($dat>$maxdate) // we need the latest trade time $maxdate=$dat; if ((isset($_GET['totalonly'])) and ($_GET['totalonly']=='yes')) $desc=''; else { // build the description sting $desc='Today:'; if ($data[5]>0) $desc.='
Open price:'.$data[5]; if ($data[6]>0) $desc.='
High price:'.$data[6]; if ($data[7]>0) $desc.='
Low price:'.$data[7]; if ($data[1]>0) $desc.='
Last price:'.$data[1]; if ($data[8]>0) $desc.='
Volume:'.$data[8]; if ($dat>0) $desc .= '
Trade date: '.date('r',$dat); if (($count>0) and ($cost>0)) $desc .= '
Value:'. '
Acquisition: '.$aq . ' ('.$count.' at '.$cost.')'. '
Current: '.$cur. ' ('.$count.' at '.$data[1].')'; if ($aq>0) $desc .= '
Difference: '.$dif.' ('.number_format((($dif/$aq)*100),2).'%)'; if (($count>0) and ($cost>0)) $desc .= '
Count: '.$count; $header = '
[1d Chart]'; break; case '1d': $graphstr .= $header.'w?b='.$symbol.'" alt="[1d Chart]" border="0" />'; break; case '5d': $graphstr .= $header.'w?s='.$symbol.'" alt="[5d Chart]" border="0" />'; break; case '3m': $graphstr .= $header.'c/3m/0/'.$symbol.'" alt="[3m Chart]" border="0" />'; break; case '6m': $graphstr .= $header.'c/6m/0/'.$symbol.'" alt="[6m Chart]" border="0" />'; break; case '1y': $graphstr .= $header.'c/1y/0/'.$symbol.'" alt="[1y Chart]" border="0" />'; break; case '2y': $graphstr .= $header.'c/2y/0/'.$symbol.'" alt="[2y Chart]" border="0" />'; break; case '5y': $graphstr .= $header.'c/5y/0/'.$symbol.'" alt="[5y Chart]" border="0" />'; break; case 'my': $graphstr .= $header.'c/my/0/'.$symbol.'" alt="[my Chart]" border="0" />'; break; } } if ($graphstr!='') $desc .= $graphstr; } if ($title=='') $title=$data[0]; else if (!$titlenoshort) $title .= ' ('.$data[0].')'; if (!$titlenovalue) $title .= ' - '.$data[1]; if (!$titlenochange) $title .= ' ('.$data[4].')'; printitem($title, // title= symbol - value (change) 'http://finance.yahoo.com/q?s='.$data[0], // link to yahoo $desc, $dat, $data[0].$dat); } // totalonly } else { printitem($symbol.' is unknown!','','','','',false); } } } // done with the individual items if (isset($_GET['total']) and ($_GET['total']=='yes')) // do we want a total? { if ($totcur>0) $procentage=($totdif/$totaq); else $procentage=0; $totalstr .= '
Total: '.$totcur.'-'.$totaq.'='.$totdif. ' ('.number_format($procentage*100,2).'%)'; if (($totcur==0) or ($totaq==0)) $totalstr='Can\'t calculate totals without stock count and acquisition price.

See:
http://blog.tc.dk/2005/01/yahoo-stock-to-rss-converter.php
for more information'; printitem('Total', '', $totalstr, $maxdate, // build the guid as the latest trade time ''); } } // isleach rssfooter(); } else { header('Content-Type: text/xml'); rssheader(); printitem('Yahoo Stock to RSS', 'http://blog.tc.dk/2005/01/yahoo-stock-to-rss-converter.php', 'You need to add some parameter to the address of this RSS feed, read more here:
http://blog.tc.dk/2005/01/yahoo-stock-to-rss-converter.php', '', '', false); rssfooter(); } ?>