SWIG typemap for ta-lib

I was trying to swig a function in ta-lib (TA-Lib provides common
functions for the technical analysis of financial market data)
http://ta-lib.org/index.html

the c functuon api

TA_RetCode TA_MA( int startIdx,
int endIdx,
const double inReal[],
int optInTimePeriod,
int optInMAType,
int *outBegIdx,
int *outNbElement,
double outReal[],
)

===========

the c call

TA_Real closePrice[400];
TA_Real out[400];
TA_Integer outBeg;
TA_Integer outNbElement;

/* … initialize your closing price here… */

retCode = TA_MA( 0, 399,
&closePrice[0],
30,TA_MAType_SMA,
&outBeg, &outNbElement, &out[0] );

/* The output is displayed here */
for( i=0; i < outNbElement; i++ )
printf( “Day %d = %f\n”, outBeg+i, out[i] );

================

the query’‘’‘’’

what should be the typemap

for argument

             1>const double inReal[],
              2>int         *outBegIdx,
              3>int         *outNbElement,
              4>double       outReal[],

=============

regards

Thanks for your lead.
It is lot clear now … how to go about it.
Still I am fuzzy on a couple of things.
Could you pl guide…

in ruby use it as
closePrice = Array.new()
data_inp = closePrice[0…399]
data_arr = ModuleExp::TA_MA( data_inp, 30, ModuleExp::TA_MAType_SMA)

So are you suggesting that i need not pass startIdx,endIdx in the
input. But these values I understand is required … this is to
sometimes specify a range on which to run the function .
What I am confused about is …ModuleExp::TA_MAType_SMA… is this a
constant that you are suggesting to pass along?

/* Get the length of the array */
{
    /* Convert Ruby Object Fixnum to unsigned char */
    $1[i]= (double)?????(*ptr); // here i don't remember the macro

to convert something like FIX2INT for float
}

here I used $1[i]= NUM2DBL(*ptr);
is that OK?

double arr_res[400];
Here I need to dimensionise the arr_res to the size of the input
array instead of 400. So i need to get the size variable in the
previous typemap declaration. But how can i use the size variable
here… it was a local variable only.

               const double inReal[],
               const double inReal[],
               int          optInTimePeriod,
               int          optInMAType,
               int         *outBegIdx,
               int         *outNbElement,
               double       outReal[])

I did not get this one clearly… TA_Retcode is the output type.
Can’t i get it in ruby?Only thing that i am getting back here is the
outReal[] array i think.

{

   int iStartIx = *arg6;
   int iLen = iStartIx + *arg7;

    VALUE arr = rb_ary_new2(iLen);

    for ( int i = iStartIx; i < iLen;  i++ )
        rb_ary_push(arr, INT2FIX((*arg8)[i]));
    $result = arr;

the *arg8 contains floating point number so will INT2FIX work?

}

it is not tested but this give you the idea how to make the i file.

Regards

Thanks again …

Regards

On 13 Mrz., 12:03, “BENI” [email protected] wrote:

              int         *outBegIdx,

TA_Real out[400];
/* The output is displayed here */

             1>const double inReal[],
              2>int         *outBegIdx,
              3>int         *outNbElement,
              4>double       outReal[],

=============

regards

in ruby use it as
closePrice = Array.new()
data_inp = closePrice[0…399]
data_arr = ModuleExp::TA_MA( data_inp, 30, ModuleExp::TA_MAType_SMA)

In .i file you should define
%typemap(in)(int startIdx,
int endIdx,
const double inReal[]
)
{

   Check_Type($input, T_ARRAY);

/* Get the length of the array */
int size = RARRAY($input)->len;
int i;
$3 = (unsigned char*) malloc(size * sizeof(double));
$2 = size;
$1 = 0;

// copy the ruby array in the new allocated buffer
/* Get the first element in memory */
VALUE *ptr = RARRAY($input)->ptr;
for (i=0; i < size; i++, ptr++)
{
    /* Convert Ruby Object Fixnum to unsigned char */
    $1[i]= (double)?????(*ptr); // here i don't remember the macro

to convert something like FIX2INT for float
}
}

%typemap(in)(int optInMAType,
int *outBegIdx,
int *outNbElement,
double outReal[]
)
{
int out_beg_ix = 0;
int out_n_ele = 0;
double arr_res[400];

$1 = NUM2INT(optInMAType);
$2 = &out_beg_ix;
$3 = &out_n_ele;
&4 = arr_res;

}

%typemap(freearg) (int startIdx,
int endIdx,
const double inReal[],
int optInTimePeriod,
int optInMAType,
int *outBegIdx,
int *outNbElement,
double outReal[]) {
free((double *) $1);
}

%typemap(out)TA_RetCode TA_MA( int startIdx,
int endIdx,
const double inReal[],
int optInTimePeriod,
int optInMAType,
int *outBegIdx,
int *outNbElement,
double outReal[]
{

   int iStartIx = *arg6;
   int iLen = iStartIx + *arg7;

    VALUE arr = rb_ary_new2(iLen);

    for ( int i = iStartIx; i < iLen;  i++ )
        rb_ary_push(arr, INT2FIX((*arg8)[i]));
    $result = arr;

}

it is not tested but this give you the idea how to make the i file.

Regards

On Mar 14, 11:45 am, “BENI” [email protected] wrote:

data_arr = ModuleExp::TA_MA( data_inp, 30, ModuleExp::TA_MAType_SMA)

int size = RARRAY($input)->len;
    /* Convert Ruby Object Fixnum to unsigned char */
             int         *outBegIdx,

previous typemap declaration. But how can i use the size variable

free((double *) $1);

Regards

Thanks again …

Regards

Sorry for some errors.
Your questions.
If you use TA_MAType_SMA in the C function and you want to use it
also in ruby, you have to export it.
In Ruby I like to use all input parameters as function parameters.
Out parameters on the left side as result. If you are also interested
an TA_Retcode you have to change the typemap(out). Afterwards you can
use in ruby this:
ta_res, data_arr_out = ModuleExp::TA_MA( data_inp, 30,
ModuleExp::TA_MAType_SMA)

in .i file:
%typemap(out)TA_RetCode TA_MA( int startIdx,
int endIdx,
const double inReal[],
int optInTimePeriod,
int optInMAType,
int *outBegIdx,
int *outNbElement,
double outReal[]
{

   int iStartIx = *arg6;
   int iLen = iStartIx + *arg7;
   VALUE arr_results = rb_ary_new2(2) // 2 elements as result
   rb_ary_push(arr_results, INT2FIX(result)); // first is

TA_Retcode

   VALUE arr_data = rb_ary_new2(iLen); // data array

    for ( int i = iStartIx; i < iLen;  i++ )
        rb_ary_push(arr_data, rb_float_new((*arg8)[i]));

    rb_ary_push(arr_results, arr_data); // second  array of data

    $result = arr_results

}

here you are right, INT2FIX doesn’t work but rb_float_new should be.
NUM2DBL for inputs should be also ok.

If you need to pass startIdx,endIdx as input, you have to modify the
typemap(in)

%typemap(in)(const double inReal[])
{

   Check_Type($input, T_ARRAY);

/* Get the length of the array */
int size = RARRAY($input)->len;
int i;
$1 = (unsigned char*) malloc(size * sizeof(double));

// copy the ruby array in the new allocated buffer
/* Get the first element in memory */
VALUE *ptr = RARRAY($input)->ptr;
for (i=0; i < size; i++, ptr++)
{
    /* Convert Ruby Object Fixnum to unsigned char */
    $1[i]= (double)NUM2DBL(*ptr);
}

}

If you don’t like a maxsize for output array, like double
arr_res[MAX_OUT_DATA];
you can use:
arg8 = (unsigned char*) malloc(size * sizeof(double));
inside %typemap(in)(const double inReal[])
I don’t know if it is exact, but you can look inside the generated
code if all is set like you want (I use swig with c++ and I expect a
function called _wrap_TA_MA inside generated code).
Don’t forget to free arg8 in the typemap.

Cheers
Igor

On Mar 15, 1:52 pm, “BENI” [email protected] wrote:

How do I make SWIG aware of my TA_Retcode type?
int arg2 ;

arg3 = (unsigned char*) malloc(size * sizeof(double));
}
int out_n_ele = 0;

{
return vresult;
fail:
return Qnil;

}

Thanks

Regards

for TA_RetCode you have to declare in .i file the header file where
TA_RetCode is defined. After %module declaration in .i you can use
%{

#include “xxxxxTA_RetCodeincludefile.h”
This to avoid compiler error in your wrap function.

To export TA_RetCode to ruby you can use, at the end of .i file, this
declaration:
%include “xxxxxTA_RetCodeincludefile.h”

I got most of your points.

I am still confused with TA_RetCode

I am being bugged by the compiler

C:\talib\ta-lib\swig\ide\msvc\talibruby\rubytalibdll
\rubytalib_wrap.c(1623) : error C2065: ‘TA_RetCode’ : undeclared
identifier

How do I make SWIG aware of my TA_Retcode type?

am I making some mistake pertaining to header inclusion in .i file ?

a snap of my wrap fn

===========================================

SWIGINTERN VALUE
_wrap_TA_MA(int argc, VALUE *argv, VALUE self) {
int arg1 ;
int arg2 ;
double *arg3 ;
int arg4 ;
int arg5 ;
int *arg6 = (int *) 0 ;
int *arg7 = (int *) 0 ;
double arg8 ;
TA_RetCode result; /
I did not get it here */
int val4 ;
int ecode4 = 0 ;
VALUE vresult = Qnil;

if ((argc < 3) || (argc > 3)) {
rb_raise(rb_eArgError, “wrong # of arguments(%d for 3)”,argc);
SWIG_fail;
}
{
Check_Type(argv[0], T_ARRAY);

/* Get the length of the array */
int size = RARRAY(argv[0])->len;
int i;
arg3 = (unsigned char*) malloc(size * sizeof(double));
arg2 = size;
arg1 = 0;

// copy the ruby array in the new allocated buffer
/* Get the first element in memory */
VALUE *ptr = RARRAY(argv[0])->ptr;
for (i=0; i < size; i++, ptr++)
{
  /* Convert Ruby Object Fixnum to unsigned char */
  arg1[i]= NUM2DBL(*ptr);
}

}
ecode4 = SWIG_AsVal_int(argv[1], &val4);
if (!SWIG_IsOK(ecode4)) {
SWIG_exception_fail(SWIG_ArgError(ecode4), “in method '” “TA_MA”
“’, argument " “4"” of type '” “int”"’");
}
arg4 = (int)(val4);
{
int out_beg_ix = 0;
int out_n_ele = 0;
double arr_res[400];

arg5 = NUM2INT(optInMAType);
arg6 = &out_beg_ix;
arg7 = &out_n_ele;
arg8 = arr_res;

}
result = TA_MA(arg1,arg2,(double const
(*))arg3,arg4,arg5,arg6,arg7,arg8);
{
int iStartIx = *arg6;
int iLen = iStartIx + *arg7;

VALUE arr = rb_ary_new2(iLen);

for ( int i = iStartIx; i < iLen;  i++ )
rb_ary_push(arr, INT2FIX((*arg8)[i]));
vresult = arr;

}
return vresult;
fail:
return Qnil;
}

Thanks

Regards

Thanks a lot for your help.

I have been able to port all the functions .

For the group info… i have built the dll .

i am writing the test cases now…

Testing will be a long affair i feel…

btw :::: if any one is interested in using it pl send me mail… i
will attach the dll

#########################################################################
just a sample of a couple of functions
#########################################################################

C:\talib\ta-lib\swig\ide\msvc\talibruby\rubytalibdll\Debug>ruby
rubytalibtest.rb

TOTAL DATA POINTS FOR TEST: 252
################################################################################

Start of Rubytalib test… Rubytalib version:0.3.0 (Mar 20 2007
07:33:13)
################################################################################

TA_MAX OUTPUT Maximum price ======>137.88
TA_MAXINDEX OUTPUT Max Index =======>131
TA_SUM of the lot ==========>27133.035
TA_MIDPOINTof the lot ==========>109.6275
TA_MA of the lot(Simple over 200 days) ==========>[108.900525,
108.882808333333,
108.864073922056, 108.686321942732, 108.539592371163,
108.393626277918, 108.265
331489083, 108.11343764342, 107.982358661893, 107.885519272223,
107.774718085435
, 107.64571591543, 107.513619239655, 107.354876759658,
107.184678980955, 107.052
891130398, 106.919230522136, 106.82053171097, 106.702914480015,
106.595124286184
, 106.470396681347, 106.352482286507, 106.227084452811,
106.145222915967, 106.12
328039939, 106.140660693924, 106.139858099954, 106.123541103935,
106.11236159046
3, 106.093233614438, 106.063052185439, 106.036753158718,
106.029123774054, 106.0
87241945457, 106.18587635396, 106.289698479791, 106.409004962579,
106.4782685947
92, 106.50336044957, 106.535167808281, 106.56218106392,
106.566537471244, 106.59
2641576008, 106.626545639928, 106.652152150974, 106.68665809972,
106.69972617833
, 106.718833380536, 106.748994242421, 106.779452011153,
106.801547016017, 106.82
0934607898, 106.831373069511]
TA_MA of the lot(Exponential over 200 days)
==========>[117.055064179104, 117.03
7347512438, 117.017659701493, 116.838161691542, 116.688085323383,
116.5373699004
97, 116.402868905473, 116.243448756219, 116.103308706468,
115.995995024876, 115.
87336119403, 115.731210945274, 115.58474800995, 115.410468159204,
115.2234987562
19, 115.073227114428, 114.919625124378, 114.799614925373,
114.659313930348, 114.
527388308458, 114.377241542289, 114.232458706468, 114.078708457711,
113.96694203
9801, 113.91362238806, 113.898365422886, 113.863886069652,
113.812656218905, 113
.765403482587, 113.709307462687, 113.641081343284, 113.575600995025,
113.5276246
26866, 113.544417164179, 113.601007960199, 113.662423134328,
113.738955223881, 1
13.765069154229, 113.746379353234, 113.733454477612, 113.714782835821,
113.67246
0696517, 113.650754228856, 113.635928855721, 113.612107960199,
113.596458208955,
113.558767412935, 113.526387562189, 113.504396766169,
113.481970646766, 113.450
549004975, 113.415719402985, 113.371152487562]

#################################################################################

Regards.

Rajib