SWIG Wrapper for TA-Lib
=======================
 vi:set tw=77:

This directory tree contains files needed to build a SWIG wrapper to 
TA-Lib. SWIG is a software development tool for building scripting language
interfaces to C and C++ programs. It supports a number of target languages:
including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby, and
Tcl.  More information can be found at http://www.swig.org

I had two goals while making this wrapper:
1. To stay as close as possible to the original TA-LIB C interface
2. To make the interface as much convenient (and "Perlish") and robust 
   as possible.
Those two objectives were often not compatible, what results in many elements
being wrapped in two or more ways; choose your own perferences.  In a few
cases, those objectives were conflicting; then the Perl way took precedence
over being literally identical to the TA-LIB C way.

Although SWIG is capable of generating wrappers to many languages, makefiles
in this directory tree support Perl only.  Taking Perl as example, one can
extend it to other laungages, if needed.

First Thing
===========
If you are a Win32 user, and you are using Perl 5.8.0, you will find in
the TA-Lib MSVC package the pre-compiled binaries. You can then directly 
jump to the section "Using TA-Lib in Perl".

Others will need to build their own binaries. Follow the step starting 
with the "Installation" section.

Installation
============
To build the wrapper, you need to have SWIG installed at your system. Get it
from http://www.swig.org.  The swig executable must be present on your search
path. Verify it at command prompt:
> swig -version

This project is tested with SWIG version 1.3.21. It should work also with
higher versions within the 1.3.x familly.  If you have a lower SWIG version, 
better upgrade.

Obviously, you need also perl installed at your system (Perl5).  The project
is tested with perl v5.6.1 and v5.8.4.  It should work with newer perl
releases as well.

Further, you need a C/C++ compiler, the same as used to compile the perl
executable you use.  At the end, we will be building perl modules.  If you
use ActivePerl on Windows (from ActiveState), you most probably need Visual
C++ version 6.0.  If you use Linux, you probably need gcc, etc.  To find it
out, try:
> perl -V

Building the Perl module
========================
Build can be done using MSVC with either the nmake utility or using the IDE.

IDE - Microsoft Developer Studio
--------------------------------
First, make sure that the proper ta-lib library is already build in
ta-lib/c/lib.  The wrapper links only with Release Multithreaded DLL variant
(because of necessary compatibility with Perl build), so you need
ta_libc_cdr.lib

Open workspace swig\ide\msvc\perl\perl.dsw and hit Build All. You can 
alternatively use "nmake" in that same directory.

make - Linux/gcc
----------------
First, make sure that the proper ta-lib library is already build in
ta-lib/c/lib.  The wrapper links only with Release Multithreaded Static
variant so you need have libta_libc_cmr.a.

cd swig/make/perl/linux/g++
make

Using ta-lib in Perl
====================
The generated perl modules are placed in ta-lib/swig/lib/perl, so make sure
that this directory is placed in your Perl lib search path.  Alternatively,
copy the modules to the appropriate places in your system, where local/site
modules belong.  Another alternative is to use "use lib" pragma in your perl
scripts.

The module name is Finance::TA.  The C identifier names are retained literally, 
so you can use the C API spec.  In case of doubt, look at examples in
ta-lib/swig/src/demo/perl and - even better - at the test scripts in 
ta-lib/swig/src/tools/test_perl.  The test scripts tend to be complete so there
is an example for every function, constant, or type.

The module covers all TA-LIB functions, a few exceptions exist.

In general, the following usage rules apply:
 * structs are turned to Perl classes, so can be created using 'new'
 * access to struct fields are provided through tied variables
    e.g.
        print $history->{period};
 * Ouput parameters are returned as elements in the return list
    e.g.  
        $ts = new TA_Timestamp;
        TA_SetDate($ts, 2004, 2, 29);
        @ret = TA_GetDate($ts);
        # @ret == ($TA_SUCCESS, 2004, 2, 29);
 * Null pointers are represented by undef

There are some exceptions and there are easier ways of doing things:

* There is no need to call &TA_Initialize.  The module initializes itself on
'use' with default parameters.  Call &TA_Initialize if you need to provide
your own init params.

* There is no need to call &TA_Shutdown, ever.  The module shuts itself down
on 'END'. Calling &TA_Initialize on already initialized library
automatically invokes &TA_Shutdown first.  If you call &TA_Shutdown, make
sure that there are no defined "TA" variables around.  Some objects make
calls to TA-LIB in their destructors.

* Instead of doing
    $rci = new TA_RetCodeInfo;
    TA_SetRetCodeInfo($retCode, $rci);
you may prefer:
    $rci = new TA_RetCodeInfo($retCode);

* As a bonus to Perl programmers, the constructor of TA_Timestamp allows for
initializing the date and time:
    $ts = new TA_Timestamp(2004, 2, 29, 9, 11, 59);
    $ts = new TA_Timestamp(2004, 2, 29);  # time set to zero
But There's More Than One Way To Do It.
    $ts = new TA_Timestamp("2004-02-29 09:11:59");
    $ts = new TA_Timestamp("2004-02-29");
To be parsed, all numbers have to be two-digit (except the year).  Superfluous
characters are ignored. Dash separators for date, colons for time.

* Some other TA_Timestamp goodies: synthesized attributes (data members):
    $y = $ts->{year};
    $m = $ts->{month};
    $s = $ts->{day};
    $ts->{hours} = 12;
    $ts->{minutes} = 30;
    $ts->{seconds} = 59;

* Do not call &TA_HistoryAlloc and &TA_HistoryFree directly.  Simply use
&TA_History::new.  The parameters to &new are the same as to
TA_HistoryAlloc(). 
E.g.:
    my $haParam = new TA_HistoryAllocParam;  # my $haParam = {}; works too
    $haParam->{category} = "US.NASDAQ.STOCKS";
    $haParam->{symbol} = "LNUX";
    $haParam->{period} = $TA_DAILY;
    $haParam->{field} = $TA_ALL;
    my $hist = new TA_History($udBase, $haParam);
    if ($hist->{retCode} == $TA_SUCCESS) {
        ...
    }
Alternatively:
    my $hist = $udBase->History($haParam);
    if ($hist->{retCode} == $TA_SUCCESS) {
        ...
    }
Alternatively:
    my $hist = $udBase->History({
            category => "US.NASDAQ.STOCKS", 
            symbol => "LNUX", 
            period => $TA_DAILY,
            field => $TA_ALL,
        });

* Note that TA_History objects are read-only.

* The TA_History member arrays are made available as references to Perl
arrays.  Examples:
    print $hist->{close}[0], "\n";
    $close_series = $hist->{close};
    print $$close_series[0], "\n";
    print "@$close_series\n";

* Note that each access to a tied member variable is going through the
thunk code from Perl to C and back, so for the sake of performance, 
consider copying the history arrays to Perl arrays.
Eg.
    # slow
    for ($i = 0;  $i < $history->{nbBars};  $i++) {
        print $history->{close}[$i], "\n";
    }
    # fast
    @close = @{ $history->{close} };
    for $close (@close) {
        print $close, "\n";
    }

* If you do this for the timestamp array, note that the Perl array contains
only the references to C Timestamp structs, not the object themselves.
The C structs fall under the authority of C hence are not reference-counted.
This means that if you undef the history, the references to timestamps become
garbage.

* Insead of doing:
    $retCode = TA_UDBaseAlloc(\$udBase);
    TA_UDBaseFree($udBase)
you may strongly prefer:
    $udBase = new TA_UDBase; 
In the former case, you have to call &TA_UDBaseFree, otherwise a memory leak
will occur.  Also, after the call to &TA_UDBaseFree, you must not use the
variable anywhere, otherwise a segmentation fault may occur.  In such case it
is safer to undef the variable directly after the call to &TA_UDBaseFree.
In the latter case, the database will be freed automatically when $udBase
goes out of scope or is redefined. If the allocation fails, $udBase will be
undef.  There is no way of getting the ret code then.  But hey, what can go
wrong with TA_UDBaseAlloc()?  And you are freed from the hurdle of keeping
track of allocation and deallocation.  This is the True Perl Way.

* The same as above applies to TA_FuncHandle, TA_FuncInfo, except that there
is no need (and no possibility) to deallocate the handles.

* Instead of TA_CategoryTableAlloc/TA_CategoryTableFree use just
&TA_CategoryTable.  This function returns a Perl list of strings, so there is
no need do deallocate it explicitly.  Note that the first list element is the
return code, as usual.  The same applies to TA_SymbolTableAlloc/Free,
TA_GoupTableAlloc/Free, TA_FuncTableAlloc/Free.

* Alternatively, you may want to use the object interface of TA_UDBase:
    @categories = $udBase->CategoryTable();
    @symbols = $udBase->SymbolTable("ZZ.OTHER.OTHER");
    @symbols = $udBase->SymbolTable(); # defaults to $TA_DEFAULT_CATEGORY
In such case, you don't have to bother about the error code; you get undef
value in case of any error.

* C functions in ta_func have three groups of parameters, input, optional
input and output.  The input parameters are startIdx, endIdx, and one or more
arrays with numbers, These are also expected parameters of the Perl
functions, with a note that in place of arrays, references to arrays are
expected.

The optional parameters can be set to $TA_INTEGER_DEFAULT/$TA_REAL_DEFAULT or
undef, or ommitted altogether.

The output parameters are retured in the return array.  The returned array
has the following structure: return code of the function, begin index, and
one or more references to output arrays.  The parameter outNbElement used in
the C functions is not passed to Perl as it can be easilly obtained by
evaluating an array in a scalar context.

Example (default optInTimePeriod):
    ($retCode, $begIdx, $outReal) = TA_MAX(0, $#inReal, \@inReal);

More examples in swig/src/tools/test_perl/ta_func.t

* Several complex TA-LIB functions accept a pointer to a struct containing
the parameters for the function invocation.  This is to avoid long argument
lists in function signatures.  Using this in Perl is rather inconvenient,
meaning that a specific object has to be created, and each of it's fields has
to be initialised explicitly through tied variables.  A simpler way exists
if you use the object-oriented interface of the wrapper.  Instead of passing
a reference to a specific object type as required by TA-LIB, you may pass
a reference to a (possibly unnamed) plain hash.  
This works for the following functions: TA_History (see example above), 
AddDataSource, TradeLogAdd.


Good luck!
Pawel Konieczny, konieczp-at-users.sourceforge.net 


Open issues/To do
=================

* How to write log files to stdout
* How to define a custom TA fatal handler in Perl
* Get parameters on "use"-line for &TA_Initialize

