[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GT] Re: Re: Bug fixes in GT::Conf
- To: devel
AT
geniustrader.org
- Subject: [GT] Re: Re: Bug fixes in GT::Conf
- From: Nick Fantes Huege <nfhuege
AT
gmail.com>
- Date: Sun, 25 Jul 2010 00:09:38 +0300
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type; bh=mPEYn3o8UtA06I84b6ecnVygC4U+kL/PtB99lr77wNk=; b=EMSrbUcP6EvAK9VHSQgIee3T5UUalLj3SlpK1/N9erjW717t/EtdezxCi1aG0OIkOU qkvv1WI2N5wtIDo7IXMBwKKyg3hjumf/LdNL6wnQAo07asp1AiCcwVHFMo7nYn2b1fS2 RP6XpXI+Mj9KaW2zZAI6DxJD5okrZD/UdUCSo=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=lEievmPT/bUNEnNu1Lu9hE1yc0M9ateyFaD1collG8NAge3XAIaMzVCJxNvQirP9GD CrNCWq9iFE2w6NupZPb8oZ+sypRuqiD6iHxvtLmmZpQdjywikAuceQtQoglvhVdE50Ys +h47vcjBW1MVy1jS9tadxa9eijHtrUKYOjwsU=
- In-reply-to: <4C4A6F0C.6080804
AT
acm.org>
- Message-id: <AANLkTimiAncNKFvOZsgvONq-dtfX+R_Wy9di1+88FDEq@mail.gmail.com> (sfid-20100724_231106_947067_A81E6FB3)
- Reply-to: devel
AT
geniustrader.org
ras,
Attached is the corrected version of Conf.pm. It performs better than
the original one based on your test configuration file.
I also put all comments and pod back.
Regards,
Nick
package GT::Conf;
# Copyright 2000-2002 RaphaÃl Hertzog, Fabien Fulhaber
# enhancements by ras copyright 2007-2008
# This file is distributed under the terms of the General Public License
# version 2 or (at your option) any later version.
# $Id: Conf.pm 690 2009-07-30 05:18:51Z ras $
use strict;
use vars qw(%conf);
=head1 NAME
GT::Conf - Manage configuration
=head1 DESCRIPTION
This module provides functions to manage personal GeniusTrader configuration.
The configuration information are stored in file ~/.gt/options by default.
The configuration file format is similar to a perl hash, in other words, a key
followed by data for that key. keys are delimited from their value by whitespace.
key values can contain embedded whitespace.
key value strings can be continued across multiple lines by delimiting the
newline with a backslash (\) (watch out for trailing whitespace after the \ and
before the newline).
comments introduced with a # as the first character on a line. data lines
cannot contain a comment since the # character is used in many data strings.
blank lines and lines with only whitespace are ignored.
=head1 EXAMPLES of ~/.gt/options Entries
# this is an example of a comment
DB::module genericdbi
DB::bean::dbname beancounter
Graphic::Candle::UpBorderColor "[0,180,80]"
Graphic::Candle::DownBorderColor "[180,0,80]"
this example shows how continuing key values across lines can be useful.
DB::genericdbi::prices_sql SELECT day_open, day_high, day_low, \
day_close, volume, date FROM stockprices WHERE symbol = '$code' ORDER \
BY date DESC
comments are permitted on data lines provided they can be distinguished from
positional arguments markers (e.g. #1, #2, etc). in order to do this any
trailing data line comment marker (#) must be surrounded by whitespace.
the code is a bit more forgiving, using this regex (\s+#[\s\D]+.$)
note that the comment must follow the end of the logical data line
and terminates at the end of the logical line. logical line means the
line after continuation processing has completed.
examples:
Aliases::Global::TFS2[] SY:TFS #1 #2 | CS:SY:TFS #1 # comment
graphic::positions::buycolor "[0,135,0]" # very dark green
graphic::buysellarrows::buycolor "[0,135,0,64]" # semitransparent dark green
note: configuration keys are lower cased automatically regardless of how
they are defined, but their values are as specified when defined
=head1 FUNCTIONS
=item C<< GT::Conf::load([ $file ]) >>
Load the configuration from the indicated file. If the file is omitted
then it looks at ~/.gt/options by default.
=cut
BEGIN {
$conf{'HOMEPATH'} = $ENV{'HOME'} || $ENV{'USERPROFILE'} || '';
}
sub load {
my $file = $_[0] || "$conf{'HOMEPATH'}/.gt/options";
if ( !-r $file ) {
warn("Could not find configuration file: $file");
return;
}
open( FILE, '<', $file ) || die "Can't read $file: $!\n";
my $line = '';
my $num = 0;
while (<FILE>) {
# Keep track of line numbers
$num++;
# Remove trailing spaces
chop while /(\n|\r|\s)$/;
# Remove leading spaces
s/^\s+//;
# Remove inline comments. Everything behind a '#' is a comment,
# except a number
s/\s*#\D+.*$//;
# Remove first '#' comments.
# Someone should merge this regex with the above.
s/^#.*//;
$line .= $_;
next if $line =~ s/\\$/ / || !$line;
# Remove extra spaces
$line =~ tr/[ \t]/[ \t]/s;
# Split the first two columns
my ( $key, $val ) = split /\s+/, $line, 2;
if ( exists $conf{ lc($key) } ) {
warn "'$key' already defined, skipping. Line $num in $file\n";
}
else {
# All config goes in lowercase
$conf{ lc($key) } = $val;
}
$line = '';
}
close FILE;
foreach my $kind (
"Signals", "Indicators",
"Systems", "CloseStrategy",
"MoneyManagement", "TradeFilters",
"OrderFactory", "Analyzers"
)
{
foreach my $file (
"$conf{'HOMEPATH'}/.gt/aliases/" . lc($kind),
GT::Conf::get("Path::Aliases::$kind")
)
{
next unless defined $file;
next if not -e $file;
open( ALIAS, "<$file" ) || die "Can't open $file : $!\n";
while (<ALIAS>) {
if (/^\s*(\S+)\s+(.*)$/) {
GT::Conf::default( "Aliases::$kind\::$1", $2 );
}
}
close ALIAS;
}
}
}
=item C<< GT::Conf::store($file) >>
Write all the current configuration in the given file. Note: all prior
commentary, if any is lost.
=cut
sub store {
my $file = $_[0] || "$conf{'HOMEPATH'}/.gt/options";
open( FILE, ">$file" ) || die "Can't write $file: $!\n";
for ( sort keys %conf ) { printf FILE "$_\t$conf{$_}\n" }
close FILE;
}
=item C<< GT::Conf::clear() >>
Clear all the configuration.
=cut
sub clear { %conf = () }
=item C<< GT::Conf::get($key,$defaultValue) >>
Return the configuration value for the given key. If the
key doesn't exist, it returns the optional defaultValue.
If neither the key nor defaultValue exist, it returns undef.
=cut
sub get { return $conf{ lc( $_[0] ) } || $_[1] || undef }
=item C<< GT::Conf::set($key, $value) >>
Set the given configuration item to the corresponding value. Replaces any
previous value.
=cut
sub set { $conf{ lc( $_[0] ) } = $_[1] }
=item C<< GT::Conf::vars >>
Returns all config values in a hash ref. Example:
my $conf = GT::Conf::vars();
print "My DB module is $conf->{'db::module'}\n";
=cut
sub vars { return \%conf }
=item C<< GT::Conf::default($key, $value) >>
Set a default value to the given item. Must be called by GT itself to
give reasonable default values to most of configurations items.
=cut
sub default {
my ( $key, $val ) = @_;
$key = lc($key);
if ( !defined( $conf{$key} ) ) {
$conf{$key} = $val;
}
}
=item C<< GT::Conf::get_first($key, ...) >>
Return the value of the first item that does have a non-zero value.
=cut
sub get_first {
my (@keys) = @_;
foreach (@keys) {
my $value = &get($_);
return $value if ( defined($value) && $value );
}
return '';
}
=item C<< GT::Conf::=_get_home_path() >>
Helper function, returns the home directory environment variable HOME on Unix
or on windows the environment variables HOMEDRIVE . HOMEPATH
=cut
sub _get_home_path { return $conf{'HOMEPATH'} }
=item C<< GT::Conf::conf_dump( [ "regex" ] ) >>
Helper function, writes the entire configure key=value pairs on stderr.
code example: GT::Conf::conf_dump;
pass a perl regex string to filter the output
=cut
sub conf_dump {
my $regex = $_[0] || '.*';
print STDERR
"gt configuration file keys and values filtered using \"$regex\"\n";
printf STDERR "%s\t%-36s\t%-s\n", "item", "key", "value";
my $i = 0;
foreach ( sort keys %conf ) {
( grep m/$regex/i, $_ )
? printf STDERR "%3d\t%-36s\t%-s\n", $i, $_, $conf{$_}
: ();
++$i;
}
print STDERR "\n\n";
}
=pod
=back
=cut
=item C<< my $gt_root_dir = GT::Conf::get_gt_root() >>
Helper function, returns the gt root directory
which is the directory that contains GT and Scripts
directories, along with any others that may be there.
if that configuration key-value is unset check for the
environment variable GT_ROOT otherwise returns an empty string
=cut
sub get_gt_root { return &get('GT::Root') || $ENV{'GT_ROOT'} || '' }
1;