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

Re: [GT] SVN Commit r623 - trunk/GT



gt'ers

ignore all my prior replies to this change notice. i'm starting over.
my prior arguments and analyzes were flawed with erroneous examples,
test cases and my simply not having a good understanding of object
aliases. hopefully i've corrected those shortcomings and can now
discuss the topic based on knowledge and actual evaluation.

i figure if i (or anyone else) actually used these object aliases
any problems they have would be easily recognized and thus solved.
but i just don't think anyone actually uses them, probably because
they are so poorly documented, have too much flexibility, and finally
because they add yet another layer of complexity on top an already too
complex system.

i'm gonna try to explain what their two different file formats are
(yes there are different formats for the different file types) in
the two file types that allow object aliases to be defined.
then i'll try to explain what the different file path options are
as far as where object aliases files are searched for.

then i'll summarize my findings about object aliases, what's broke
what's not and well what's what. lastly, i will attempt, once more,
to comment on the object alias changes that have been committed
under this change notice.

for such a simple, little used feature, object aliases certainly
have a wide variety of alternatives, pitfalls and gotchas, no good
error detection/messaging and little documentation.


object aliases

object aliases are user defined aliases, shorter names for commonly
used gt object specifications. object aliases can be used for any
of the gt analysis component specifications like Signals, Indicators,
as well as gt system component specifications like Systems, CloseStrategy,
TradeFilters and the like. it isn't clear whether an object alias may
be used to define multiple components of a system (e.g. contain a connecting
'|' symbol). the code commentary, and pod implies that is not their
intended purpose, for that it's probably just wiser to use a system alias.

to mark an object aliases in a gt component specification prefix the
@ symbol to the specification. if you have an object alias named
my_mean and it is an indicator type it would appear as @I:my_mean
in a gt specification.

examples of object aliases are presented in paragraphs below.


object alias formats

there are two different formats that object aliases come in. which
form depends on which type of file the object aliases is defined in.
the two file types that can define an object aliases are
   $HOME/.gt/options
and
   the $kind files that can appear at
   $HOME/.gt/aliases/$kind
and also in the directory(ies) defined by %conf keys "Path::Aliases::$kind"
(case insensitive) which by default is the path(s) /usr/share/geniustrader/aliases/$kind

the variable $kind assumes each of these filenames during alias loading:
 signals
 indicators
 systems
 closestrategy
 moneymanagement
 tradefilters
 orderfactory
 analyzers


starting with object aliases defined in the users $HOME/.gt/options file
the format is:
  "Aliases::Indicators::"<my_object_alias> <whitespace> <object_alias specification>

where the string "Aliases::Indicators::" must be prepended without the quotes
to the object_alias name. this string is separated by whitespace from
the <object_alias specification> string. note that when entries are added to
the gt %conf hash the keys are lower cased, but the values are stored unaltered.

here are working examples -- for use only in your $HOME/.gt/options file
 # example use: display_indicator.pl @I:MyMean GOOG '50 {I:RSI}'
 Aliases::Indicators::MyMean_opt	{ I:Generic:Eval ( #1 + #2 ) / 2 }
 Aliases::Indicators::PVOL_opt		{I:Prices VOLUME}


the second form of an object alias format differs in that the string
"Aliases::$kind::" must not be part of the key, as it is derived from
the file name ($kind) as the file is loaded. the "Aliases::$kind::"
string will be automatically added to the object alias name when
the object alias is added to the gt %conf hash. this format applies
to object aliases found in any of the files named using $kind.

the second form of an object alias format is:
   <my_object_alias> <whitespace> <object_alias specification>


examples of the second form of an object alias format:
 MyMean_gbl	{ I:Generic:Eval ( #1 + #2 ) / 2 }
 PHI_gbl	{I:Prices VOLUME}
and
 PO	{I:Prices OPEN}
 PH	{I:Prices HIGH}
 Pl	{I:Prices LOW}
 PC	{I:Prices CLOSE}
 PV	{I:Prices VOLUME}
 vol	{I:Prices VOLUME}


object alias file locations

there are two places in the file system where object alias files are
looked for. in search order they are:
1) $HOME/.gt/options/aliases/$kind    # fixed locations, cannot be altered
   note: alias files in this directory tree must be name after $kind
   and must be lower case (if your os/fs is case sensitive).

2) the values of the gt %conf hash keys Path::Aliases::$kind.
   by default the root of this path is /usr/share/geniustrader/aliases
   the files therein bearing the names of each $kind.
   note: the default files name after $kind are lower case, but if you
   elect to change the default whatever case you specify will be used.

   these paths are under full user control using the gt %conf option
   keys Path::Aliases::$kind to establish paths other than the default.
   that gt configuration option key value pair looks like:
       Path::Aliases::$kind	'/this/users/preferred/path/alias_file'
   note that there is no requirement that values that $kind takes on
   (e.g. indicator, signal, etc) appear in the actual path, but it is
   necessary that the key contain those $kind values (keys are case
   insensitive). furthermore it is expected that the appropriate type
   of object aliases be in the file found at the associated path.
   in other words, the file named by the value of key
   Path::Aliases::Indicators should contain indicator aliases.

   i haven't evaluated the effect of putting signal object aliases in
   files expected to be indicators.

my suggestion, if you need to have a shared place for object aliases
and cannot use the default root (e.g. /usr/share/geniustrader/aliases/).
for the sanity of your maintainers and developers at least use $kind
filenames where ever else you set the path.


referring to the second form example object aliases above, i've got
the first two in this pathname:
   /usr/local/src/genius_trader/ind_aliases
which i've enabled by adding the following to my $HOME/.gt/options file:
 # change default from /usr/share/geniustrader/aliases to gt area
 Path::Aliases::Indicators	/usr/local/src/genius_trader/ind_aliases

i don't recommend doing this in practice, but it's a good example to explain
how flexible the mechanism for storing object aliases is and how easy
it is to get yourself tangled up in it.

the remaining 6 example object aliases are in file $HOME/.gt/aliases/indicators


pathname upper/lower case observations

the $kind filenames in dir tree $HOME/.gt/aliases will be lower case.

the default $kind filenames in the dir tree /usr/share/geniustrader/aliases
will be lower case.

if you change the default $kind pathname using the Path::Aliases::$kind
config options whatever pathnames you specify will be used without change.

gt config option keys are always case insensitive and are stored lower case.

completely valid object alias files stored in an appropriate directory tree
but having a case conflict will be silently ignored. my suggestion would
be to avoid using upper case pathnames.



thing not achieved or not evaluated

i haven't evaluated the effect of putting signal object aliases in
files expected to be indicators.

i have not been able to get an object alias that references another
object alias to work. either recursion isn't supported or i'm unable
to properly specify the recursive alias correctly.

i haven't made the effort to evaluate object alias argument substitution,
that being plugging in the correct arguments for #1, #2, $n placeholders.

finally i haven't made the effort to ensure that the arithmetic operators
( + - * / ) work.


findings and other observations:

  i) GT::Tools::resolve_object_alias reloads all alias files for every
     object alias encountered.

 ii) object aliases don't appear to allow recursion

iii) two different object aliases specification formats is confusing

 iv) multiple object aliases file locations is confusing

  v) case is ignored when resolving object_aliases names

 vi) lower case is normally use for standard and default pathnames to
     object alias files, but if you alter the default pathnames you
     will get what ever case you specify

vii) silently ignoring standard and default pathnames that aren't
     lower case

viii) lack of useful error messages when object alias resolution fails



ok now what is broken and needs fixing and what is not broke but
could be improved and what is not broke at all.

broken
i) multiple loading is a defect -- i dislike the solution implemented
   in this change notice moving object alias loading into the
   GT::Conf::load method. preferring instead the semaphore fix
   i proposed. it's simpler, it doesn't change the GT::Conf::load method,
   and doesn't change the GT::Tools::resolve_object_alias that much either.
   refer to "Re: [GT] SVN Commit r623 - trunk/GT" dated 08may08 for details.


due to lack of use, interest and utility of object aliases i see little
point in doing much more than improving documentation for the rest of these
issues.

improvable
iii) solve by providing better documentation
  or
    change code to combine the different forms (s/// regex should do it)
  or
    eliminate one or the other alternatives

  -- my position is leave it alone if it isn't broke. don't
     remove features and flexibility just because it's confusing,
     little used or poorly documented without a very good reason.
     add better documentation

iv) solve by providing better documentation

  -- my position is this dual search scheme allows the sharing of
     object aliases and it is a good thing. it works, once it's understood.

     the default paths being wrong 'because they are not under every
     users control' is not a valid argument -- that path was chosen
     specifically because it might be a controlled area. besides, if
     the user, or using group wants to use a different path they can
     change it by adding entries like:
         Path::Aliases::Indicators	/usr/local/src/genius_trader/my_indicator_aliases
     in their $HOME/.gt/options file.

vi) solve by providing better documentation
  or
    change code and documentation to support only the case mix desired,
    but the change must apply across the board to filepaths defined
    using the Path::Aliases::$kind option as well as the fixed paths
    at $HOME/.gt/aliases/$kind

  -- my position is leave it alone if it isn't broke. don't
     remove features and flexibility just because it's confusing,
     little used or poorly documented without a very good reason.
     add better documentation

vii) could be improved, but is it worth it?

viii) could be improved, but is it worth it?


not broke
ii) that's the way it works -- i don't care
 v) that's the way it works -- i don't care




i'm hoping that some one will jump on this note, fix the grammatical errors, fix
the technical errors, fill in the missing parts, add better examples, convert it
into perl pod, and submit it as the missing object_aliases.pod man page.

one can always hope



aloha

ras


GeniusTrader SVN wrote:
Author: thomas
Date: 2008-05-03 03:36:52 +0200 (Sat, 03 May 2008)
New Revision: 623

Modified:
   trunk/GT/Conf.pm
   trunk/GT/Tools.pm
Log:
Correct alias resolution per RAS suggestion. Avoid repeated loading of object aliases. Remove hard-wired paths for object alias files.

Modified: trunk/GT/Conf.pm
===================================================================
--- trunk/GT/Conf.pm	2008-04-26 22:04:45 UTC (rev 622)
+++ trunk/GT/Conf.pm	2008-05-03 01:36:52 UTC (rev 623)
@@ -98,6 +98,28 @@
 	$conf{lc($key)} = $val;
     }
     close FILE;
+
+    # Load the various definition of aliases
+ + foreach my $kind ("Signals", "Indicators", "Systems", "CloseStrategy", + "MoneyManagement", "TradeFilters", "OrderFactory",
+                      "Analyzers")
+    {
+        foreach my $file (GT::Conf::_get_home_path()."/.gt/aliases/".lc($kind),
+         GT::Conf::get("Path::Aliases::$kind"))
+	{
+	    next unless defined $file;
+	    next if not -e $file;

humm the two statements above do exactly the same thing do they not?

i guess the first one (next unless defined $file;) was needed to inhibit
an uninitialized message because the the default paths were removed.
all the more reason to restore those default values!

+            open(ALIAS, "<", "$file") || die "Can't open $file : $!\n";
+	    while (defined($_=<ALIAS>)) {
+		if (/^\s*(\S+)\s+(.*)$/) {
+		    GT::Conf::default("Aliases::$kind\::$1", $2);
+		}
+	    }
+	    close ALIAS;
+	}
+    }
+
 }
=item C<< GT::Conf::clear() >>

Modified: trunk/GT/Tools.pm
===================================================================
--- trunk/GT/Tools.pm	2008-04-26 22:04:45 UTC (rev 622)
+++ trunk/GT/Tools.pm	2008-05-03 01:36:52 UTC (rev 623)
@@ -182,7 +182,7 @@
          .  "\nkey looked for was \"Aliases::Global::$name\"\n";
     }
     # The alias content may list another alias ...
-    while ($sysname !~ /^(I|Indicators|SY|Systems|S|Signals|CS|CloseStrategy|MM|MoneyManagement|TF|TradeFilters|OF|OrderFactory|A|Analyzers|PortfolioEvaluation)/i) {
+    while ($sysname !~ /:/) {
 	$sysname = resolve_alias($sysname);
     }
     my $n = 1;
@@ -212,11 +212,21 @@
 Return the complete description of the object designed by "alias". @param
 is the array of parameters as returned by GT::ArgsTree::parse_args().
-Object aliases can be defined in global files
-(/usr/share/geniustrader/aliases/indicators for example) or in custom
-files (~/.gt/aliases/indicators) or in the standard configuration file
-with entries like this one :
+Object aliases can be defined in global files (as defined in the option
+Path::Aliases::<object_kind>), for each kind of object (e.g., Signals, +Indicators, etc.), or in user-specific files (~/.gt/aliases/<object_kind>). +Such aliases are defined via the syntax
+  <alias_name>   <definition>
+
+For example
+  MyMean  { I:Generic:Eval ( #1 + #2 ) / 2 }
+
+An object alias can also be defined in the option file with the syntax
+  Aliases::<object_kind>::<alias_name>    <definition>
+
+For example:
+
  Aliases::Indicators::MyMean  { I:Generic:Eval ( #1 + #2 ) / 2 }
Then you can use this alias in any other place where you could have used
@@ -231,34 +241,6 @@
 sub resolve_object_alias {
     my ($alias, @param) = (@_);
- # Load the various definition of aliases
-    GT::Conf::default('Path::Aliases::Signals', '/usr/share/geniustrader/aliases/signals');
-    GT::Conf::default('Path::Aliases::Indicators', '/usr/share/geniustrader/aliases/indicators');
-    GT::Conf::default('Path::Aliases::Systems', '/usr/share/geniustrader/aliases/systems');
-    GT::Conf::default('Path::Aliases::CloseStrategy', '/usr/share/geniustrader/aliases/closestrategy');
-    GT::Conf::default('Path::Aliases::MoneyManagement', '/usr/share/geniustrader/aliases/moneymanagement');
-    GT::Conf::default('Path::Aliases::TradeFilters', '/usr/share/geniustrader/aliases/tradefilters');
-    GT::Conf::default('Path::Aliases::OrderFactory', '/usr/share/geniustrader/aliases/orderfactory');
-    GT::Conf::default('Path::Aliases::Analyzers', '/usr/share/geniustrader/aliases/analyzers');
- - foreach my $kind ("Signals", "Indicators", "Systems", "CloseStrategy", - "MoneyManagement", "TradeFilters", "OrderFactory",
-                      "Analyzers")
-    {
-        foreach my $file (GT::Conf::_get_home_path()."/.gt/aliases/".lc($kind),
-         GT::Conf::get("Path::Aliases::$kind"))
-	{
-	    next if not -e $file;
-            open(ALIAS, "<", "$file") || die "Can't open $file : $!\n";
-	    while (defined($_=<ALIAS>)) {
-		if (/^\s*(\S+)\s+(.*)$/) {
-		    GT::Conf::default("Aliases::$kind\::$1", $2);
-		}
-	    }
-	    close ALIAS;
-	}
-    }
- # Lookup the alias
     my $def = GT::Conf::get("Aliases\::$alias");