Stock Charts

Demo of a perl-script database application thingy.

See jim_README.txt and http://biz.swcp.com/stocks/ for the source and massaging of the data.


Pick a company to display:  
% if ($menuCompany) {
<% $menuCompany %>
% }
Last modified: Fri Feb 22 04:31:20 EST 2002
<%args> $menuCompany => "" %# ======================================================== <%init> # A kludge, but I'm still not sure that opening and reading # files happens in this directory. my $dir = "/home/msie/html/2002/ipl/perl/lectures/feb22/S_and_P/"; my $stockfile = $dir . "all_stocks.txt"; my $companyfile = $dir ."companies.txt"; my @companies = companyNames($dir); sub companyNames { my ($dir) = @_; open(FILE, "<$dir"."companies.txt") or return ("Oops", "companies not found"); my @companies = ; foreach my $company (@companies) { chomp($company); } close(FILE); return @companies; } sub doGraph { my ($dir,$company,$stockfile) = @_; my $graphfile = "$dir$company.png"; my $returnfile = "$company.png"; unless (-e $graphfile) { # file doesn't exist yet, so make it. use Text::CSV; my $csv = Text::CSV->new(); open(STOCKS, "<$stockfile") or return "mc-logo.gif"; my $xmin = 1e9; my $xmax = 0; # year 10000 > any year I care about my $ymin = 1e9; my $ymax = 0; # higher stock price than any I've seen my @x = (); my @y = (); my $line; while ($line = ) { # loop over 127k lines of file chomp($line); if ($line =~ /$company/) { my $status = $csv->parse($line); my @columns = $csv->fields(); # sample line: 20010222,YUM,37,37.48,36.59,37.11,5410 my $x = $columns[0]; # date, 200002222 = 2000 Feb 22 my $y = $columns[5]; # closing price next if $x < 20000000; # only keep dates after Jan 01 2000 $x = convertDate( $x ); $xmax = $x if $x > $xmax; $xmin = $x if $x < $xmin; $ymax = $y if $y > $ymax; $ymin = $y if $y < $ymin; push @x, $x; push @y, $y; } } close(STOCKS); plotPoints($graphfile, \@x, \@y, $xmin, $xmax, $ymin, $ymax) or return "mc-logo.gif"; } return $returnfile; } sub convertDate { use Date::Calc qw( Date_to_Days ); my ($date) = @_; my $day = $date % 100; my $month = (($date - $day) / 100) % 100; my $year = ($date - $day - 100*$month)/10000; return Date_to_Days( $year, $month, $day); } sub plotPoints{ use GD; my ($graphfile, $xx, $yy, $xmin, $xmax, $ymin, $ymax) = @_; my @x = @$xx; my @y = @$yy; my $xpixsize = 384; # size of plot in pixels my $ypixsize = 256; my $xpixborder = 10; my $ypixborder = 10; my $xconvert = $xpixsize/($xmax - $xmin); my $yconvert = $ypixsize/($ymax - $ymin); my $im = GD::Image->new($xpixsize+2*$xpixborder, $ypixsize+2*$ypixborder); my $white = $im->colorAllocate(255,255,255); my $darkblue = $im->colorAllocate(0,0,128); $im->transparent($white); $im->interlaced('true'); my $xpixleft = $xpixborder + ((shift @x)-$xmin)*$xconvert; my $ypixleft = $ypixborder + ($ymax - (shift @y))*$yconvert; my $xpixright; my $ypixright; while (@x) { $xpixright = $xpixborder + ((shift @x) - $xmin)*$xconvert; $ypixright = $ypixborder + ($ymax - (shift @y))*$yconvert; $im->line($xpixleft,$ypixleft,$xpixright,$ypixright,$darkblue); $xpixleft = $xpixright; $ypixleft = $ypixright; # for (my $i=0;$i<50;$i++) { shift @x; shift @y }; } open(GRAPH, ">$graphfile") or return 0; print GRAPH $im->png; close(GRAPH); return 1; }