#!/Perl

# from : http://www.foo.be/docs/tpj/issues/vol3_2/tpj0302-0008.html
# http://www.cbot.com/mplex/quotes/tsfut/tsf$Contract.htm
###print "Hello, World...\n";
my $Contract = "12345678";

#use LWP::Simple;
#my $URL = 'http://www.cbot.com/mplex/quotes/tsfut';
#my $text = get("$URL/tsf$Contract.htm");

#
#use Win32::Internet;
#my $URL = 'http://www.cbot.com/mplex/quotes/tsfut';
#my $text = $Win32::Internet->new->FetchURL("$URL/tsf$Contract.htm");

### some pages
# Corn Futures TIme & Sales (C)
# Time and Sales
# Open auction
# 6Jul http://www.cbot.com/cbot/pub/page/0,3181,1196+2006N,00.html
# 6Sep http://www.cbot.com/cbot/pub/page/0,3181,1196+2006U,00.html
# 6Dec http://www.cbot.com/cbot/pub/page/0,3181,1196+2006Z,00.html
# 7Mar http://www.cbot.com/cbot/pub/page/0,3181,1196+2007H,00.html
# 7May http://www.cbot.com/cbot/pub/page/0,3181,1196+2007K,00.html
# 7Jul http://www.cbot.com/cbot/pub/page/0,3181,1196+2007N,00.html
# 7Sep http://www.cbot.com/cbot/pub/page/0,3181,1196+2007U,00.html
# 7Dec http://www.cbot.com/cbot/pub/page/0,3181,1196+2007Z,00.html
# 8Mar http://www.cbot.com/cbot/pub/page/0,3181,1196+2008H,00.html
# 8Dec http://www.cbot.com/cbot/pub/page/0,3181,1196+2008Z,00.html
# Electronic
# 6Jul http://www.cbot.com/cbot/pub/page/0,3181,1308,00.html
# Oats Futures Time & Sales (O) 
# http://www.cbot.com/cbot/pub/page/0,3181,1403,00.html
# DJIA Futures ($10) Futures Time & Sales (DJ) 
# 6Sep http://www.cbot.com/cbot/pub/page/0,3181,1591,00.html

use LWP::Simple;
my $page = '0,3181,1196,00.html';
my $URL = 'http://www.cbot.com/cbot/pub/page';
my $CODE = 'C';

# just for LOG FILE ouput ...
my ($LOG);
my $write_log = 0;
my $verb = 1; # increase to 9 to see more output
my $outfile = "temp.$0.txt"; # note name of perl file used as base
if ( open( $LOG, ">$outfile" ) ) {
    $write_log = 1; # we have a LOG file
} else {
    $write_log = 0;
    prt( "WARNING: Unable to open $outfile LOG ...\n" );
}

my $out_lines = 0;
my $out_date = 1;

my $text = '';
prt( "Fetching $URL/$page ...\n");
my $text2 = get("$URL/$page");
my $llen = length($text2);
prt( "Got $llen characters ...\n" );
my $line = '';
my @Bars = ();

###prt( "[$text2]\n" );
while( $text2 =~ /\n/ ) {
	$text2 =~ s/\n/<br>/g;
}
my @lines = split( /<br>/, $text2 );
my $lcnt = scalar @lines;
prt( "Got $lcnt lines of text ...\n" );
# searching for 
# Date           Com    Mth     Price      Time       Type           Volume
#----------    -----  -------- ------    ---------   ------------   -----------
#06/16/2006      C    06Jul    2350     9:30:03 AM
my $cnt = 0;

foreach $line (@lines) {
	while ($line =~ /  /) { # double space
		$line =~ s/  / /g; # substitute single
	}

	$_ = $line;
    my ($Date,$Price,$Hour,$Min,$Sec,$ampm,$Ind) = 
         m|^\s*(\d+/\d+/\d+) # " 03/12/1998"
            \s+C\s+\S+\s+(\d+) # " C 98Mar 12116"
            \s+(\d+):(\d+):(\d+) # " 12:42:40"
            \s+(\w{2}) 	# AM/PM
			\s*(.*)$|x; # " Ask"

	$cnt++;
	#if (defined $Date) {
	#	prt( "$cnt $line " );
	#	prt( " date $Date $Price $Hour $Min $Sec $ampm $Ind\n" );
	#} else {
	#	###prt( " NO DATE\n" );
	#}

    next unless defined $Date;
    $Day = $Date;
	
    # Convert from fractional to decimal format
    $Price = int($Price/100) + ($Price%100)/32;

	if ((($ampm =~ /^PM/i)||($Ind =~ /^PM/i)) && ($Hour < 12)) {
		$Hour += 12;
	}

    # Round up time to next multiple of 15 minutes
    my $NewTime = int(($Sec+$Min*60+$Hour*3600)/900+1)*900;
	###prt( "New time = $NewTime ...\n" );
	if (defined $Time && !($NewTime == $Time)) {
		prt( "$cnt $line " );
		prt( " D[$Date] P[$Price] H[$Hour] M[$Min] S[$Sec] M[$ampm] I=[$Ind]\n" );
	} elsif ($out_date) {
		prt( "$cnt $line " );
		prt( " D[$Date] P[$Price] H[$Hour] M[$Min] S[$Sec] M[$ampm] I=[$Ind]\n" );
	}

    unless (defined $Time && ($NewTime == $Time)) {
		if (defined $Time) {
			prt( "Pushing $hhmm, $Open, $High, $Low, $Close ...\n" );
		    push @Bars, [$hhmm, $Open, $High, $Low, $Close];
			prt( "Updating Time $Time to New Time $NewTime ...\n" );
		} else {
			prt( "First set of Time to New Time $NewTime ...\n");
		}
        $Open = $High = $Low = $Close = undef;
        $Time = $NewTime;
        my $Hour = int($Time/3600);
        $hhmm = sprintf "%02d:%02d", $Hour, $Time/60-$Hour*60;
    } elsif (defined $Time) {
		###prt( "Time = NewTime, ($Time = $NewTime) ...\n" );
    } else {
		prt( "Time NOT defined ...\n" );
	}
	
    # Update 15 minute bar values
    $Close = $Price;
    $Open = $Price unless defined $Open;
    $High = $Price unless defined $High && $High > $Price;
    $Low = $Price unless defined $Low && $Low > $Price;
	###prt( "Next $hhmm, $Open, $High, $Low, $Close ...\n" );

}

foreach (split "\n", $text) {
    # 03/12/1998 US 98Mar 12116 15:28:34 Open
    my ($Date,$Price,$Hour,$Min,$Sec,$Ind) =
         m|^\s*(\d+/\d+/\d+) # " 03/12/1998"
            \s+US\s+\S+\s+(\d+) # " US 98Mar 12116"
            \s+(\d+):(\d+):(\d+) # " 12:42:40"
            \s*(.*)$|x; # " Ask"
    next unless defined $Date;
    $Day = $Date;
	
    # Convert from fractional to decimal format
    $Price = int($Price/100) + ($Price%100)/32;
	
    # Round up time to next multiple of 15 minutes
    my $NewTime = int(($Sec+$Min*60+$Hour*3600)/900+1)*900;
    unless (defined $Time && $NewTime == $Time) {
		if (defined $Time) {
			prt( "Pushing $hhmm, $Open, $High, $Low, $Close ...\n" );
		}
        push @Bars, [$hhmm, $Open, $High, $Low, $Close]
                                          if defined $Time;
        $Open = $High = $Low = $Close = undef;
        $Time = $NewTime;
        my $Hour = int($Time/3600);
        $hhmm = sprintf "%02d:%02d", $Hour, $Time/60-$Hour*60;
    }
	
    # Update 15 minute bar values
    $Close = $Price;
    $Open = $Price unless defined $Open;
    $High = $Price unless defined $High && $High > $Price;
    $Low = $Price unless defined $Low && $Low > $Price;
	prt( "Next $hhmm, $Open, $High, $Low, $Close ...\n" );
}

mydie( "No data found\n" ) unless defined $Time;
prt( "Pushing $hhmm, $Open, $High, $Low, $Close ...\n" );
push @Bars, [$hhmm, $Open, $High, $Low, $Close];

# diagnostic line output only
if ($out_lines) {
	foreach $line (@lines) {
		chomp $line;
		$line =~ s/\t/ /g; # substitute the tabs to a space
		while ($line =~ /  /) { # double space
			$line =~ s/  / /g; # substitute single
		}
		if ($line =~ /\S/) { # if other than white space
			prt( "$line\n");
		}
	}
}

exit(0);

################################
### output and log file
sub wlog {
	my $ml = shift;
	print $LOG $ml;
}

sub prt {
	my $m = shift;
	if ($write_log) {
		wlog($m);
	}
	print STDOUT $m;
}

sub mydie {
	my $msg = shift;
	if ($write_log) {
		wlog($msg);
	}
	die $msg;
}

sub close_log {
	if ($write_log) {
		prt( "Closing LOG file, and passing to 'system($outfile)'\nMay need to CLOSE notepad to continue ...\n" );
		close( $LOG );
		system( $outfile );
	}
}
