| |
channel.pl - Simulating channel-based futures
trading
# Simulate basic channel system
# M. Edward Borasky, 26-DEC-96
# usage: perl channel.pl <contract> <days>
# where <contract> is the contract name and <days> is the
# number of days in the channel.
$start = time(); # starting time stamp
# open hardcoded input file
$contract = $ARGV[0]; # contract name
$infile = “a:\\pinnacle\\clc\\temp\\${contract}_clc.asc";
open(INPUT, $infile);
print "Input from $infile\n";
$days = $ARGV[1]+0; # number of days in channel
print "Days in channel = $days\n";
# open output file
$outfile = "${contract}.prn";
open(OUTPUT, ">> $outfile");
print "Output to $outfile\n";
@high = @low = (); # allocate saved data arrays empty
$position = 0; # start neutral
$rollflag = 0; # first day is regular record
# main loop over data file
while (<INPUT>) { # read a line
@F = split(’ ’, $_); # split into fields
$date = $F[0]+0; # date
if ($date == 0) { # rollover record
$rollflag = 1; # set rollover flag
$offset = $F[4] - $F[1]; # compute offset
} else { # regular data record
$open = $F[1]+0; # opening price
$high = $F[2]+0; # day’s high
$low = $F[3]+0; # day’s low
$close = $F[4]+0; # closing price
$trdays++ if $position != 0; # days in trade
if ($rollflag) { # this is a rollover day
&backadjust; # back adjust data
&rolltrade; # do rollover trade
&newdata; # update data buffer/stops
$rollflag = 0; # reset flag
printf("%s %d Rollover %6g %12.9g\n", $contract, $days, $date, $offset);
} else { # regular day
&trades; # simulate any trades
&newdata; # update data buffer/stops
}
}
}
$stop = time(); $minutes = ($stop - $start)/60; # elapsed time
printf ("%s %d Elapsed minutes=%6g\n", $contract, $days, $minutes);
printf OUTPUT ("%s %d Elapsed minutes=%6g\n", $contract, $days, $minutes);
close(INPUT);
close(OUTPUT);
sub rolltrade { # trades on rollover day
return if $#high < ($days - 1); # not enough data
if ($open >= $buystop && $position != 1) {
&closeshort($open - $offset);# close short
&openlong ($open); # open new long
} elsif ($open <= $sellstop && $position != -1) {
&closelong($open - $offset); # close long
&openshort($open); # open new short
} elsif ($high >= $buystop && $position != 1) {
&closeshort($buystop - $offset);
&openlong ($buystop);
} elsif ($low <= $sellstop && $position != -1) {
&closelong($sellstop - $offset);
&openshort($sellstop);
} elsif ($position == -1) { # holding short
&closeshort($close - $offset); # close
&openshort ($close); # open new
} elsif ($position == 1) { # holding long
&closelong($close - $offset);# close
&openlong ($close); # open new
}
}
sub backadjust { # adjust past price data on rollover day
for ($ix = 0; $ix <= $#high; $ix++) { # adjust back data
$high[$ix] += $offset;
$low[$ix] += $offset;
}
$buystop += $offset; # and stops
$sellstop += $offset;
}
sub trades { # simulate any trades for this day
return if $#high < ($days - 1); # not enough data
if ($open >= $buystop && $position != 1) {
&closeshort($open); # close any open short
&openlong ($open); # open new long
} elsif ($open <= $sellstop && $position != -1) {
&closelong($open); # close any open long
&openshort($open); # open new short
} elsif ($high >= $buystop && $position != 1) {
&closeshort($buystop);
&openlong ($buystop);
} elsif ($low <= $sellstop && $position != -1) {
&closelong($sellstop);
&openshort($sellstop);
}
}
sub newdata { # add today’s data, drop oldest point
push(@high, $high); # today’s high
push(@low, $low); # today’s low
if ($#high >= $days) { # buffer full
shift(@high); shift(@low); # drop oldest
}
# search for stops
$buystop = $high[0];
$sellstop = $low[0]; # init
for ($ix = 1; $ix <= $#high; $ix++) { # search
$buystop = $high[$ix] if $high[$ix] > $buystop;
$sellstop = $low[$ix] if $low[$ix] < $sellstop;
}
}
sub closeshort { # close out any short position
return if $position != -1; # not short -- go away
$price = $_[0]; # argument is price
# print to trade log
print OUTPUT "$contract $days -1 ";
printf OUTPUT ("%6g %12.9g %6g %12.9g %d\n",
$opendate, $paid, $date, $price ,$trdays);
$position = 0; # we’re neutral
}
sub closelong { # close out any long position
return if $position != 1; # not long -- go away
$price = $_[0]; # argument is price
# print to trade log
print OUTPUT "$contract $days 1 ";
printf OUTPUT ("%6g %12.9g %6g %12.9g %d\n",
$opendate, $paid, $date, $price ,$trdays);
$position = 0; # we’re neutral
}
sub openlong {
return if $position == 1; # already long -- go away
$paid = $_[0]; # argument is price
$trdays = 0; # days in trade
$position = 1; # we’re now long
$opendate = $date; # remember when we opened trade
}
sub openshort {
return if $position == -1; # already short -- go away
$paid = $_[0]; # argument is price
$trdays = 0; # days in trade
$position = -1; # we’re now short
$opendate = $date; # remember when we opened trade
}
|