[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[MacPerl] Help with Quotemonster



Quotemonster or qm is perl script that downloads historical quotes from the 
internet. It was working fine with Os 8.5.1 until all of a sudden it stared 
truncating the quotesout dates. For example a normal quotesout ( output) looks 
like this:

AOL,061799,106.5,113.75,103,110.6875,31982600
AOL,061899,112,113.5,109.5625,112,22946900

the faulty quotesout looks like this:

AOL,0617,106.5,113.75,103,110.6875,31982600
AOL,0618,112,113.5,109.5625,112,22946900

note the disappearance of the year-99.

I cannot figure it out. I upgraded to os 8.6-still same problem.
your help will be most appreciated.
I have attached the qm script.

#!/usr/bin/perl
#
#   IMPORTANT: READ THIS IN ITS ENTIRETY. YOU ARE THE FINAL AUTHORITY IN 
DETERMINING
#   WHAT HAPPENS ON YOUR COMPUTER. YOU SHOULD READ ALL DOCUMENTATION PERTAINING 
TO
#   THE INSTALLATION AND USE OF ALL SOFTWARE YOU INSTALL AND USE AND SHOULD 
MAKE 
#   REGULAR AND COMPLETE BACKUPS OF YOUR IMPORTANT DATA.
#
#   QuoteMonster - Download and parsing script for retrieving
#   stock quote data from Yahoo. 
#
#   -------------------------LEGAL 
INFO--------------------------------------------
#
#   This script is Copyright (C) 1998  Jim Michael and XMLWorks All Rights 
Reserved
#
#   This is version 1.0.2m (16 Dec 1998) By G Michel
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#   Download and parsing script for www.yahoo.com. This script will most
#   assuredly NOT work with other quote sources. Contact us for assistance
#   if you would like to use this script for other quote sources.
#
#   ------------------------------USAGE 
INFO-------------------------------------
#
#   USAGE: qm start_date end_date
#
#   REQUIRED FORMAT OF START AND END DATES: yymmdd
#
#   IMPORTANT USAGE NOTES: This script resulted from the merging of the 
QuoteMonster
#   Daily and QuoteMonster Historical scripts. You can now download both your 
daily
#   and historical data using just this script. The date arguments start_date 
and 
#   end_date are now OPTIONAL. If no date argument is given then QuoteMonster 
will
#   default to today's date. If only one date argument is given then 
QuoteMonster will
#   download data for that date only. If both start_date and end_date are given 
then
#   QuoteMonster will download data for that date range. If no date argument is 
given
#   then QuoteMonster will use its group download mode and send several quote 
requests
#   at once, greatly increasing the speed of daily downloads of large numbers 
of quotes.
#   
#   YEAR 2000 NOTE: Date formats of Y2K compliant charting programs are not 
know yet.
#   Until it is known what the new format, if any, might be it is impossible to 
produce
#   a Y2K compliant version of the program. Once a year format is established 
and charting
#   programs are updated to use the new format, QuoteMonster may be modified to 
handle the
#   new date format, probably by making the year field use four digits, per the 
configuration
#   option below.
#
#   IMPORTANT NOTE RE MUTUAL FUNDS: Only the closing price is available using 
QuoteMonster 
#   to download mutual fund prices. Consequently you should not mix mutual fund 
tickers
#   with stock and index ticker in the same ticker file or your import program 
may generate
#   errors. To handle both types of data, keep a copy of the QuoteMonster 
script in two 
#   different directories, using one for stocks and index downloads and one for 
mutual funds.
#   You may also need to use a header at the top of your data file such as:
#
#   <date>,<ticker>,<close>
#
#   Note to Windows NT/95 users:
#
#   If you are on a Win32 platform (NT or Windows95/98) then we HIGHLY 
recommend that you
#   use Gurusamy Sarathy's Standard Win32 port of Perl 5.04 or higher. The 
ActiveState port
#   is newer, but this version is known to be stable and included all of the 
modules used
#   by QuoteMonster. You may download the free perl interpreter from
#   http://www.perl.com/ or see the XMLWorks website for location of the binary 
download.
#
#
#   ----------------------------------SUPPORT 
INFO--------------------------------------
#
#   A newsgroup for QuoteMonster has been created on DejaNews. You can access 
it at:
#
#             
#       
#http://www.dejanews.com/[LB=http://xmlworks.com/quotemonster/,LBT=Return%20to%2
0XM#LWorks]/group/dejanews.members.biz.quotemonster.quotemonster
#
#   Email: quotemonster@xmlworks.com
#
#   Since this is free software, no support is offered. However, suggestions 
for improvements
#   to the program are always welcome. If you are using the program and find it 
useful,
#   please drop us a line sometime. We would enjoy hearing from you.
#
#   Snail Mail: XMLWorks
#               PO Box 941124
#               Atlanta, GA 31141-1124
#               USA 
#   Web: http://www.xmlworks.com/
#
#   Custom modifications to this script or other custom Internet programming
#   in Perl are also available.
#
#
# ----------------------- Enter your custom settings here 
----------------------------- #
#
# Instructions:
#
# Lines with comments are preceded by the hash symbol (#). The following lines 
assign
# values to variables. Some values are numerical and some are not. The 
numerical values
# are not enclosed in single quotes, the non-numerical entries are enclosed in
# single quotes ('like this'). All perl statements must end with a semicolon 
(;) and a
# comment may follow on the same line by placing the hash symbol (#) before the 
comment. 
# QuoteMonster reads the tickers to download from a tickers file, outputs the 
raw data
# to a temporary file, then converts the data in the temporary file into a 
format 
# suitable for importing to Metastock or other charting programs and stores the 
data
# in a data file. You may use the default settings here or change as needed:

#MacPerl 
#Still needs some date work - gm
$ARGV[0] = MacPerl::Ask("What is the start date (yymmdd)?","$date1");
$ARGV[1] = MacPerl::Ask("What is the end date (yymmdd)?","$date2");

# my $tickerfile  = 'tickers.txt';        # file containing tickers - one 
ticker per line
my $tickerfile  = MacPerl::Ask("What is the name of the tickers 
file?","tickers.txt");
my $inputFile   = 'quotes.csv';         # temporary file to store quote data 
before parsing
my $outputFile  = 'quotesout';         # file to store quote data after 
parsing

# Enter the order in which the price, date, and volume information should be 
stored.
# If you do not want an item to be saved, enter a zero (0).
my $t = 1;
my $d = 2;                                      # date
my $o = 3;                                      # open
my $h = 4;                                      # high
my $l = 5;                                      # low
my $c = 6;                                      # close
my $v = 7;                                      # volume

# Some charting programs may require the date year to be expressed as either a 
two or four
# digit year. Enter the number of digits to represent the year - enter either 2 
or 4.

my $y = 4;

# If your data file must contain a header, enter it here. An example of an 
optional
# Metastock header is on the next line following the #. You must make sure you 
have the
# correct order and number of data fields:
# my $header = '<date>,<ticker>,<open>,<high>,<low>,<close>,<vol>';

my $header = '';

# QuoteMonster can remove carets (^) from tickers of indices, such as ^OEX.
# If you do not want to remove carets, set the following value to 1. If you 
want
# to remove the carets, set the following value to 0 (default):

my $donotremovecarets = 0;

# Some chart programs want quotes in a particular date order. If you need to 
reverse the order
# of dates in the QuoteMonster output file set the following value to 1. If the 
date order
# does not matter you can leave it set at the default of 0.

my $reverse_order = 0;

# Enter domain and port information
# ONLY if you must go through a proxy server:

my $proxy   = '';                             # proxy server
my $port    = '';                             # proxy server port
my $noproxy = '';                             # local domain


# ---- Do not change anything below this line unless you know what you are 
doing ---- #
print "QuoteMonster has started...\n";
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
my $ticker;
my $last;
my $date;
my $time;
my $change;
my $open;
my $high;
my $low;
my $vol;
my $data;
my @quotes;
my $startdate = shift;
my $enddate = shift;
my $daily = 0;
unless (defined($startdate)) {
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
localtime(time);
        $mon++;
        $mday = '0' . "$mday" unless $mday > 9;
        $mon = '0' . "$mon" unless $mon > 9;
	$startdate = $year . $mon . $mday;
	$daily = 1;
	print "No date arguments given so using fast daily update mode\n";
}
$enddate = $startdate unless defined($enddate);
my $startday = substr($startdate,4,2);
my $startmonth = substr($startdate,2,2);
my $startyear = substr($startdate,0,2);
my $endday = substr($enddate,4,2);
my $endmonth = substr($enddate,2,2);
my $endyear = substr($enddate,0,2);
my $request;
my $day;
my $month;
my $year;
my $line;
my $i;

# RESET HISTORY FILE TO ZERO AND ADD HEADER IF REQUIRED:
unlink $inputFile, $outputFile;
open (HISTORY, ">$outputFile") || die("Can't clear history file - $outputFile: 
$!");
if (length($header)>0) {
	print "Adding header to $outputFile\n";
	print HISTORY "$header\n";
}
close HISTORY;
       
my %mon = 
('Jan','1','Feb','2','Mar','3','Apr','4','May','5','Jun','6','Jul','7','Aug','8'
,'Sep','9','Oct','10','Nov','11','Dec','12');
my $product_id="Mozilla/3.0";
my $ua = new LWP::UserAgent;
$ua->agent($product_id);
if ($proxy ne '' && $port ne '' && $noproxy ne '') {
	$ua->proxy('http', "http://$proxy:$port/"); 
	$ua->no_proxy("$noproxy"); 
}
open (TICKERS,"$tickerfile") || die("Can't open ticker file - $!");
my @tickers = (<TICKERS>);
close TICKERS;
chomp @tickers;
if ($daily == 0) {
	my $URL = 'http://chart.yahoo.com/table.csv?s=';
	foreach $ticker (@tickers) {
		$URL .= $ticker . '&a=' . $startmonth . '&b=' . $startday . '&c=' . 
$startyear . '&d=' . $endmonth . '&e=' . $endday . '&f=' . $endyear . 
'&g=d&q=q';
		print "Retrieving $URL\n";
		$request = new HTTP::Request('GET', $URL);
		$data = $ua->request($request)->as_string;print "BEFORE DATA:$data\n";
# Changes a unix return to a Mac return - all \n are not equal
		$data =~ s/\012/\015/gs;print "AFTER DATA:$data\n";
		open (OUT, ">$inputFile");
		print OUT "$data";
		close OUT;
		open (IN,"$inputFile") || die("Can't open $inputFile - $!");
		(@quotes) = (<IN>);
		chomp @quotes;
		open (HISTORY, ">>$outputFile") || die("Can't open output file for writing - 
$!");
		foreach (@quotes) {
			if (/^\d/) {
				($date,$open,$high,$low,$last,$vol) = split(/,/);
				$ticker =~ tr/a-z/A-Z/;
				$donotremovecarets || $ticker =~ s/\^//;
				($day,$month,$year) = split(/\-/, $date);
				$day = ('0' . "$day") if ($day < 10 && $day !~ /^0/);
				$month = $mon{$month};
				$month = ('0' . "$month") if ($month < 10 && $month !~ /^0/);
				$year = substr($year,2,2);
				$date = "$year$month$day";
				$line = '';
				if (defined($high)) {
					for ($i = 1; $i < 8; $i++) {
						$line .= $ticker . ',' if ($t == $i);
						$line .= $date . ',' if ($d == $i);
						$line .= $open . ',' if ($o == $i);
						$line .= $high . ',' if ($h == $i);
						$line .= $low . ',' if ($l == $i);
						$line .= $last . ',' if ($c == $i);
                                                $line .= $vol . ',' if ($v == 
$i && defined($vol));
					}
					$line =~ s/,+$//;
				}
				else {
					$line = $ticker . ',' . $open;
				}
				print HISTORY "$line\n";
			}
		}
		close HISTORY;
		close IN;
		$URL = 'http://chart.yahoo.com/table.csv?s=';
		sleep 5;
	}
}
else {
	my $URL = 'http://quote.yahoo.com/d/quotes.csv?s=';
	my $testLength = length($URL);
	my $count = 0;
	foreach $ticker (@tickers) {
		$ticker =~ tr/A-Z/a-z/;
		$URL .= $ticker.'+';
		$count++;
		if ($count == 20) {
			qet_quotes($URL);
			$count = 0;
			$URL = 'http://quote.yahoo.com/d/quotes.csv?s=';
		}
	}
	if (length($URL) > $testLength) {
		qet_quotes($URL);
	}
	open (IN,"$inputFile") || die("Can't open $inputFile - $!");
	@quotes = <IN>;
	chomp @quotes;
	open (DAILY, ">$outputFile") || die("Can't open output file for writing - 
$!");
	if ($header ne '') {
		print DAILY "$header\n";
	}
	foreach (@quotes) {
		if (/^"/) {
			($ticker,$last,$date,$time,$change,$open,$high,$low,$vol) = 
split(/,/);
			$ticker =~ s/"//g;
			$ticker =~ tr/a-z/A-Z/;
			$date =~ s/"//g;
			if ($date ne 'N/A') {
				($month,$day,$year) = split(/\//, $date);
				if ($month > 12) {
					die("FATAL ERROR: Improper date format.");
				}
				$year = substr($year,2,2) if ($y == 2);
				$day = ('0' . "$day") if ($day < 10);
				$month = ('0' . "$month") if ($month < 10);
				$date = "$year$month$day";
				$line = '';
				for ($i = 1; $i < 8; $i++) {
					$line .= $ticker . ',' if ($t == $i);
					$line .= $date . ',' if ($d == $i);
					$line .= $open . ',' if ($o == $i);
					$line .= $high . ',' if ($h == $i);
					$line .= $low . ',' if ($l == $i);
					$line .= $last . ',' if ($c == $i);
					$line .= $vol . ',' if ($v == $i && $vol ne 'N/A');
				}
				$line =~ s/,$//;
				print DAILY "$line\n";
			}
		}
	}
	close DAILY;
	close IN;
}
if ($reverse_order) {
	print "Reversing date sequence\n";
	my $tempfile = 'quotes.~mp';
	unlink $tempfile;
	rename $outputFile, $tempfile || die "Could not rename $outputFile $!";
	open (IN,$tempfile) || die "Could not open $tempfile $!";
	open (OUT, ">$outputFile") || die "Could not open $outputFile $!";
	my @quotes = (<IN>);
	if ($header ne '') {
		$header = shift @quotes;
		push @quotes, $header;
	}
	@quotes = reverse @quotes;
	print OUT @quotes;
	close IN;
	close OUT;
	
}

sub qet_quotes {
	$URL = shift;
	$URL =~ s/\+$//;
	$URL .= '&f=sl1d1t1c1ohgv&e=.csv';
	print "Retrieving $URL\n";
        my $ua = new LWP::UserAgent;
	my $request = new HTTP::Request('GET', $URL);
        my $response = $ua->request($request);
	if ($response->is_success) {
		$data = $ua->request($request)->as_string;
                $data =~ s/\x0D//g;
		open (OUT, ">>$inputFile");
		print OUT "$data";
		close OUT;
		sleep 5;
	}
	else {
		open (OUT,">>error.log") || die("Can't open error log: $!");
		print OUT "\nError retrieving $URL \n";
		print OUT $response->error_as_HTML;
		close OUT;
	}
} 

__END__
AA
AAPL
AEP
AGC
AIG
AIT
ALD
ALT
AMP
AMZN
AOL
ARC
ASM
AVP
AXP
BA
BAC
BAX
BAY
BBY
BC
BCC
BDK
BEL
BHI
BKS
BMG
BMY
BNI
BPA
BS
C
CAT
CCI
CEN
CGP
CHA
CHV
CI
CL
COL
CPB
CQ
CSC
CSCO
CSDS
DAL
DD
DIS
DOW
EK
ETR
F
FDX
FLR
GD
GE
GM
GMH
GT
GTR
HAL
HELE
HET
HIG
HM
HNZ
HON
HRS
HWP
IBM
IC
IFF
IKN
INTC
INTL
IP
JNJ
JPM
KEY
KM
KO
LTD
MAY
MCD
MER
MKG
MMM
MO
MOB
MRK
MSFT
MTC
MZON
NPR
NSC
NSCP
NSM
NT
ODP
OEX
ONE
ORCL
OXY
PCG
PEP
PFE
PG
PHG
PNU
PPW
PRD
PRMA
RAL
ROK
S
SLB
SO
SPX
STK
T
TAN
TEK
TMX
TOL
TOY
TSO
TX
TXN
UCM
UIS
UK
USB
UTX
VIX
VNTV
WCOM
WMB
WMT
WY
XON
XRX
Z