[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GT] usability enhancement of scan.pl and sig-sys descriptions
gt'ers
all the recent (say prior 200 days or so) usage issues with scan.pl got me
using (well, more like messin') with it more and more. because it supports
multiple sig-sys descriptions in a single system_file and processes multiple
system_files per invocation one either has to manage many files containing
sig-sys descriptions, or remember (recognize) the meaning/purpose of each
sig-sys description that it (scan.pl) prints in it's output.
consequently i've been trying to identify a way to annotate the actual
sig-sys description that will not affect anything but scan.pl and not
burden the user with any significant additional effort.
i believe that there are no other gt scripts (Scripts/*.pl) that use a
scan.pl type system_file. if that belief is true, then i've found a simple
(relatively) alteration to scan.pl (and sig-sys descriptions) that allows
a user to 'name' or 'id' a sig-sys description however they please. in
addition, existing unmodified sig-sys descriptions will continue to work
just as they do now.
(humm -- possible that the backtest scripts also use same type of system_file.
in that case, changes might be needed to these scripts (backtests) to
maintain compatibility and/or add similar enhancements. i don't use the
backtests so i've not looked at this.)
also note that i've yet to test/evaluate this change use with a system
description -- all the examples are for signals. again, i don't use gt
systems as they seem to be (pick any or all or add your own) too fragile,
more trouble than worth, are not well understood (by this user), etc.
i'm looking for trial usage comments, alternative suggestions, etc before
taking this to the next level.
aloha
ras
the changes:
here's an example of a typical signal description:
S:G:And \
{S:G:CrossOverUp {I:SMA 5} {I:SMA 20}} \
{S:G:Increase {I:ADX}}
here's an example of the same signal description with the optional id string:
S:G:And \
{S:G:CrossOverUp {I:SMA 5} {I:SMA 20}} \
{S:G:Increase {I:ADX}} \
ID adx sma crossover buy signal
the last line is the new part, the string ' ID ' introduces the trailing
signal identifying string. the code allows either ID or NAME to introduce the
id string.
see attached file for changes to scan.pl (sorry these diffs are not based on
the current repository version; plus i can almost guarantee patch will not be
able to handle this manually hacked diff file. save a scan.pl backup and
cut-paste the changes. i'm looking for user comment/critique before committing.)
the complexity is in the output section. as changed, if the sig-sys description
doesn't detect any codes the output will be 'no signal', prior to this change
scan.pl only listed the sig-sys description.
in addition, if the option --verbose is set both the sig-sys description and the
id string, if one has been provided, will be printed.
with a scan_mkt_file containing:
AA
AAPL
AAUK
APA
APC
ARG
ARII
AUY
AVAV
AXE
AXP
BBL
CLF
DVN
GTLS
GLW
and a scan_example_desc containing:
S:G:And \
{S:G:CrossOverUp {I:SMA 3} {I:SMA 23}} \
{S:G:Increase {I:ADX}} \
S:G:And \
{S:G:CrossOverUp {I:SMA 5} {I:SMA 20}} \
{S:G:Increase {I:ADX}} \
ID adx sma crossover buy signal \
S:G:And \
{ S:G:Below { I:Prices CLOSE } { I:G:PeriodAgo } } \
{ S:G:Below { I:Prices CLOSE } { I:SMA 50 {I:Prices CLOSE} } } \
NAME below 50 day sma sell \
actual output on 24apr08 of
ras [ 14370 ] % ./scan.pl --start '6 months ago' --end today \
scan_mkt_file today scan_example_desc
Signal: S:G:And {S:G:CrossOverUp {I:SMA 3 {I:Prices CLOSE}} {I:SMA 23 {I:Prices CLOSE}}} {S:G:Increase {I:ADX 14 {I:Prices HIGH} {I:Prices LOW} {I:Prices CLOSE}}}
no signal
Signal Name: adx sma crossover buy signal
no signal
Signal Name: below 50 day sma sell
AA ALCOA INC
AUY YAMANA GOLD INC
AXE ANIXTER INTL INC
--- scan.pl.new Fri Mar 21 22:57:07 2008
+++ scan.pl Thu Apr 24 12:36:28 2008
@@ -325,27 +325,66 @@
blank lines and lines that start with # are comments and ignored.
note if you comment out the first line of multi-line sys-sig desc
- the entire is effectively commented out.
+ the entire sys-sig desc is effectively commented out.
- example
+ example of a commented out signal description entry
# the following signal description is commented out
#S:Generic:And {S:Generic:Above {I:Prices} {I:EMA 30}} \
{S:Generic:Above {I:Prices} {I:EMA 150}}
+=head2 this ras hack of scan.pl adds support for sig-sys description names
+
+ by adding a string to the end of a signal or system description this
+ version of scan.pl will print that string instead of the complete
+ sig-sys description in the output. if verbose is set both will be
+ printed. the sig-sys description name must be added to the end of
+ the sig-sys description and must be formatted as follows:
+
+ <whitespace> "ID" or "NAME" <whitespace> <string of your choosing>
+
+ note: either "ID" or "NAME" upcased without the quotes
+
+ examples of named signal description entries
+
+ S:G:And \
+ {S:G:CrossOverUp {I:SMA 5} {I:SMA 20}} \
+ {S:G:Increase {I:ADX}} \
+ ID adx sma crossover buy signal \
+
+ S:G:And \
+ { S:G:Below { I:Prices CLOSE } { I:G:PeriodAgo } } \
+ { S:G:Below { I:Prices CLOSE } { I:SMA 50 {I:Prices CLOSE} } } \
+ NAME below 50 day sma sell \
+
+ output (non-html) from the above two will look something like this:
+
+ Signal Name: adx sma crossover buy signal
+ CX CEMEX SAB DE CV A
+
+ Signal Name: below 50 day sma sell
+ ABV COMP DE BEBA AM A
+ GFA GAFISA SA ADR
+
=cut
if ( $line =~ /\\$/ ) {
$line =~ s/\\$//; # remove \
$buf = ''; # reset line buffer
}
- next if ($line =~ /^#|^\s+#|^$/);
+ next if ($line =~ /^\s*#|^$/); # remove comment and blank lines
# squeeze out extra spaces
$line =~ tr/[ \t]/[ \t]/s; # squeeze out multiple adjacent whitespaces
- # divide line into two pieces first word and rest of line
+ # divide line into pieces: first word, description, name id string
- if ($line =~ /^\s*(\S+)\s*(.*)$/) {
+ #if ($line =~ /^\s*(\S+)\s*(.*)$/) {
+ if ( $line =~ /^\s*(\S+)\s*(.+?)(\s(ID|NAME)\s(.+))*$/ ) {
+
+ my $desc_name = '';
+ if ( $3 ) {
+ ( $desc_name = $5 ) =~ s/\s*$//;
+ }
my $object = create_standard_object($1, $2);
my $number = extract_object_number($1);
@@ -370,9 +474,17 @@
} else {
$systems->{$name}{"signals"} = [];
}
+
+ # store user id (name)
+ $systems->{$name}{'user_id'} = $desc_name;
}
}
+if ( $#list_systems < 0 ) {
+ $err_msg = "$prog_name: error: no systems loaded\n";
+ die $err_msg;
+}
+
# Create the MsqQueue to collect the results
my $msg = IPC::Msg->new(IPC_PRIVATE, S_IRWXU);
@@ -498,34 +623,81 @@
if (ref($object) =~ /GT::Systems/) {
print "<p>" if ($html);
print "\nBuy signal: $name\n";
+
+ if ( $systems->{$name}{'user_id'} ) {
+ if ( $verbose ) {
+ print "\nBuy Signal: $name\n";
+ print "Buy Signal Name: $systems->{$name}{'user_id'}\n";
+ } else {
+ print "\nBuy Signal Name: $systems->{$name}{'user_id'}\n";
+ }
+ } else {
+ print "\nSell Signal: $name\n";
+ }
+
print "</p>" if ($html);
print "<ul>" if ($html);
- foreach my $code (sort scan_sort_sub @{$systems->{$name}{'buy_signals'}}) {
- display_item($db, $code, $html, $url);
- }
+
+ if ( $#{ $systems->{$name}{'buy_signals'} } >= 0 ) {
+ foreach my $code (sort scan_sort_sub @{$systems->{$name}{'buy_signals'}}) {
+ display_item($db, $code, $html, $url);
+ }
+ } else {
+ print " no signal\n";
+ }
print "</ul>" if ($html);
+
print "<p>" if ($html);
print "\nSell signal: $name\n";
+ if ( $systems->{$name}{'user_id'} ) {
+ if ( $verbose ) {
+ print "\nSell Signal: $name\n";
+ print "Sell Signal Name: $systems->{$name}{'user_id'}\n";
+ } else {
+ print "\nSell Signal Name: $systems->{$name}{'user_id'}\n";
+ }
+ } else {
+ print "\nSell Signal: $name\n";
+ }
+
print "</p>" if ($html);
print "<ul>" if ($html);
- foreach my $code (sort scan_sort_sub @{$systems->{$name}{'sell_signals'}}) {
- display_item($db, $code, $html, $url);
- }
+
+ if ( $#{ $systems->{$name}{'sell_signals'} } >= 0 ) {
+ foreach my $code (sort scan_sort_sub @{$systems->{$name}{'sell_signals'}}) {
+ display_item($db, $code, $html, $url);
+ }
+ } else {
+ print " no signal\n";
+ }
print "</ul>" if ($html);
+
} elsif (ref($object) =~ /GT::Signals/) {
print "<p>" if ($html);
- print "\nSignal: $name\n";
+
+ if ( $systems->{$name}{'user_id'} ) {
+ if ( $verbose ) {
+ print "\nSignal: $name\n";
+ print "Signal Name: $systems->{$name}{'user_id'}\n";
+ } else {
+ print "\nSignal Name: $systems->{$name}{'user_id'}\n";
+ }
+ } else {
+ print "\nSignal: $name\n";
+ }
+
print "</p>" if ($html);
print "<ul>" if ($html);
- foreach my $code (sort scan_sort_sub @{$systems->{$name}{'signals'}}) {
- display_item($db, $code, $html, $url);
- }
+
+ if ( $#{ $systems->{$name}{'signals'} } >= 0 ) {
+ foreach my $code (sort scan_sort_sub @{$systems->{$name}{'signals'}}) {
+ display_item($db, $code, $html, $url);
+ }
+ } else {
+ print " no signal\n";
+ }
print "</ul>" if ($html);
+
}
}
$db->disconnect;