talib_ruby 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile ADDED
@@ -0,0 +1,55 @@
1
+ h2. talib-ruby
2
+
3
+ Ruby Wrapper for "ta-lib":http://ta-lib.org/
4
+
5
+ This project has been started by Timur Adigamov on "Rubyforge":http://rubyforge.org/projects/talib-ruby/,
6
+ but since it didn't build on my machine and wasn't complete i modified it slightly, et voila.
7
+
8
+ h3. Install and build instructions
9
+
10
+ Install ta-lib from "MacPorts":http://www.macports.org/ports.php?by=name&substr=ta-lib:
11
+
12
+ bc. sudo port install ta-lib
13
+
14
+ Install the ruby wrapper talib_ruby:
15
+
16
+ bc. sudo env ARCHFLAGS="-arch PLATFORM" gem install talib_ruby -- --with-talib-include=ABSOLUTE_PATH_TO_TALIB_HEADERS --with-talib-lib=ABSOLUTE_PATH_TO_TALIB_LIBS
17
+
18
+ * PLATFORM = [i386 | x86_64 | ...]
19
+ * ABSOLUTE_PATH_TO_TALIB_HEADERS = The path to the ta-lib header files (e.g. /opt/local/var/macports/software/ta-lib/0.4.0_0/opt/local/include/ta-lib)
20
+ * ABSOLUTE_PATH_TO_TALIB_LIBS = The path to the ta-lib lib files (e.g. /opt/local/var/macports/software/ta-lib/0.4.0_0/opt/local/lib)
21
+
22
+ Now ta-lib can be used by using _require 'talib_ruby'_
23
+ Works on Leopard and Snow Leopard. Has not been tested on Windows.
24
+
25
+ h3. Example
26
+
27
+ Calculation of Moving Average (MA):
28
+
29
+ bc.. require 'rubygems'
30
+ require 'talib_ruby'
31
+
32
+ # init input data
33
+ a = Array.new
34
+ 10.times { |i| a.push i.to_f }
35
+
36
+ 10.times do |k|
37
+ b = Array.new(10)
38
+ l = TaLib::Function.new("MA")
39
+ # setup input parameter
40
+ l.in_real(0,a)
41
+ # setup optional parameter
42
+ l.opt_int(0,k+2)
43
+ # setup output parameter
44
+ l.out_real(0,b)
45
+ lookback = l.lookback
46
+ l.call(0,9)
47
+ p "k=#{k+2}"
48
+ p b
49
+ end
50
+
51
+ h3. Useful links
52
+
53
+ * "TA-Lib Forum":http://www.tadoc.org/forum/index.php?board=9.0
54
+ * "XML explanation":http://ta-lib.svn.sourceforge.net/viewvc/ta-lib/trunk/ta-lib/ta_func_api.xml?view=markup of all supported Functions
55
+ * "C/C++ API Documentation":http://ta-lib.org/d_api/d_api.html
data/example/ma.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'talib_ruby'
3
+
4
+ # init input data
5
+ a = Array.new
6
+ 10.times { |i| a.push i.to_f }
7
+
8
+ 10.times do |k|
9
+ b = Array.new(10)
10
+ l = TaLib::Function.new("MA")
11
+ # setup input parameter
12
+ l.in_real(0,a);
13
+ # setup optional parameter
14
+ l.opt_int(0,k+2)
15
+ # setup output parameter
16
+ l.out_real(0,b)
17
+ lb = l.lookback
18
+ l.call(0,9)
19
+ p "k=#{k+2}"
20
+ p b
21
+ end
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("talib")
4
+
5
+ have_library("ta_lib", "TA_Initialize")
6
+ create_makefile("talib")
data/ext/talib/talib.c ADDED
@@ -0,0 +1,540 @@
1
+ #include "ruby.h"
2
+ #include "ta_abstract.h"
3
+
4
+ static VALUE rb_mTaLib;
5
+ static VALUE rb_cTAFunction;
6
+ static VALUE rb_sInParamInfo;
7
+ static VALUE rb_sOptInParamInfo;
8
+ static VALUE rb_sOutParamInfo;
9
+
10
+ #ifndef RUBY_19
11
+ #ifndef RARRAY_LEN
12
+ #define RARRAY_LEN(v) (RARRAY(v)->len)
13
+ #endif
14
+ #ifndef RARRAY_PTR
15
+ #define RARRAY_PTR(v) (RARRAY(v)->ptr)
16
+ #endif
17
+ #ifndef RSTRING_PTR
18
+ #define RSTRING_PTR(v) (RSTRING(v)->ptr)
19
+ #endif
20
+ #endif
21
+
22
+
23
+ #define TA_INPUT_PARAM 1
24
+ #define TA_OPTION_INPUT_PARAM 2
25
+ #define TA_OUTPUT_PARAM 3
26
+ #define IN_CNT 7 // allow up to 7 arrays of input
27
+ #define OUT_CNT 3 // allow up to 3 arrays of outputs
28
+ // combine all heap storage to this struct and free only this on ta_free
29
+ typedef struct _ph {
30
+ TA_ParamHolder *p;
31
+ double* in[IN_CNT]; // johnribera@Hotmail: the usual case (double)
32
+ double* out[OUT_CNT];
33
+ } ParamHolder;
34
+
35
+ /* :nodoc: */
36
+ // get TA_FuncInfo by name
37
+ static const TA_FuncInfo* abstract_layer_get_func_info(VALUE name)
38
+ {
39
+ TA_RetCode ret_code;
40
+ const TA_FuncHandle *handle;
41
+ const TA_FuncInfo *the_info;
42
+
43
+ ret_code = TA_GetFuncHandle( RSTRING_PTR(name), &handle );
44
+ if ( ret_code == TA_SUCCESS )
45
+ {
46
+ ret_code = TA_GetFuncInfo( handle, &the_info );
47
+ if ( ret_code == TA_SUCCESS )
48
+ return the_info;
49
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetFuncInfo");
50
+ }
51
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetFuncHandle");
52
+ }
53
+
54
+ // get function parameter info
55
+ static VALUE ta_func_param_info(int param_type, VALUE self, VALUE name, VALUE index)
56
+ {
57
+ TA_RetCode ret_code;
58
+ const TA_FuncHandle *handle;
59
+
60
+ ret_code = TA_GetFuncHandle( StringValuePtr(name), &handle );
61
+ if ( ret_code == TA_SUCCESS )
62
+ {
63
+ switch (param_type)
64
+ {
65
+ case TA_INPUT_PARAM:
66
+ {
67
+ const TA_InputParameterInfo *param_info;
68
+
69
+ ret_code = TA_GetInputParameterInfo( handle, FIX2INT(index), &param_info );
70
+ if (ret_code != TA_SUCCESS)
71
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetInputParameterInfo");
72
+ return rb_struct_new(rb_sInParamInfo, INT2FIX(param_info->type), rb_str_new2(param_info->paramName), INT2FIX(param_info->flags),NULL);
73
+ }
74
+ break;
75
+ case TA_OPTION_INPUT_PARAM:
76
+ {
77
+ const TA_OptInputParameterInfo *param_info;
78
+
79
+ ret_code = TA_GetOptInputParameterInfo( handle, FIX2INT(index), &param_info );
80
+ if (ret_code != TA_SUCCESS)
81
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetOptInputParameterInfo");
82
+ // FIXME: helpFile = Qnil
83
+ // FIXME: dataSet = Qnil
84
+ return rb_struct_new(rb_sOptInParamInfo, INT2FIX(param_info->type), rb_str_new2(param_info->paramName), INT2FIX(param_info->flags), rb_str_new2(param_info->displayName), Qnil, rb_float_new(param_info->defaultValue), rb_str_new2(param_info->hint), Qnil, NULL);
85
+ }
86
+ break;
87
+ case TA_OUTPUT_PARAM:
88
+ {
89
+ const TA_OutputParameterInfo *param_info;
90
+
91
+ ret_code = TA_GetOutputParameterInfo( handle, FIX2INT(index), &param_info );
92
+ if (ret_code != TA_SUCCESS)
93
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetOutputParameterInfo");
94
+ return rb_struct_new(rb_sOutParamInfo, INT2FIX(param_info->type), rb_str_new2(param_info->paramName), INT2FIX(param_info->flags),NULL);
95
+ }
96
+ break;
97
+ } // switch
98
+ }
99
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetFuncHandle");
100
+ }
101
+
102
+ static double* FLT2DBL(double **dest, VALUE in_array)
103
+ {
104
+ VALUE *inp;
105
+ int i;
106
+
107
+ if NIL_P(in_array) return 0;
108
+
109
+ inp = RARRAY_PTR(in_array);
110
+ if (*dest) free(*dest); // only on 1st use do we skip this step
111
+ *dest = calloc(1, sizeof(double) * RARRAY_LEN(in_array));
112
+ for (i = 0; i < RARRAY_LEN(in_array); i++)
113
+ (*dest)[i] = NUM2DBL(inp[i]);
114
+ return *dest;
115
+ }
116
+
117
+ void init_tables()
118
+ {
119
+ // temporary variable return code
120
+ TA_RetCode ret_code;
121
+ // functions group table
122
+ TA_StringTable *group_table;
123
+ // define class variable @@groups - array of function groups
124
+ // define class variable @@functions - hash of array of functions
125
+ ret_code = TA_GroupTableAlloc( &group_table );
126
+ if( ret_code == TA_SUCCESS )
127
+ {
128
+ // functions table
129
+ TA_StringTable *function_table;
130
+ // ruby array for functions group table
131
+ VALUE rb_group_table = rb_ary_new();
132
+ // ruby hash for functions
133
+ VALUE rb_function_table = rb_hash_new();
134
+ unsigned i, j;
135
+
136
+ for( i=0; i < group_table->size; i++ )
137
+ {
138
+ // temporary ruby array for group's function table
139
+ VALUE rb_temp_func_table = rb_ary_new();
140
+
141
+ rb_ary_push(rb_group_table, rb_str_new2(group_table->string[i]));
142
+ ret_code = TA_FuncTableAlloc( group_table->string[i], &function_table );
143
+ if( ret_code == TA_SUCCESS )
144
+ {
145
+ for ( j=0; j < function_table->size; j++)
146
+ rb_ary_push(rb_temp_func_table, rb_str_new2(function_table->string[j]));
147
+ rb_hash_aset(rb_function_table, rb_str_new2(group_table->string[i]), rb_temp_func_table);
148
+ TA_FuncTableFree ( function_table );
149
+ }
150
+ }
151
+ rb_define_class_variable( rb_cTAFunction, "@@groups", rb_group_table );
152
+ rb_define_class_variable( rb_cTAFunction, "@@functions", rb_function_table );
153
+ TA_GroupTableFree( group_table );
154
+ }
155
+ }
156
+
157
+ // free function
158
+ static void ta_func_free(void *phv)
159
+ {
160
+ int i = 0; // this now properly cleans up memory from very last call
161
+ ParamHolder* ph = (ParamHolder*)phv;
162
+ for (i = 0; i < IN_CNT; i++) if (ph->in[i]) free(ph->in[i]);
163
+ for (i = 0; i < OUT_CNT; i++) if (ph->out[i]) free(ph->out[i]);
164
+ TA_ParamHolderFree( ph->p );
165
+ free(ph);
166
+ }
167
+
168
+ // allocation function
169
+ static VALUE ta_func_alloc(VALUE klass)
170
+ {
171
+ ParamHolder *param_holder;
172
+ // call calloc() to ensure we set all values (ptrs to NULL/0)
173
+ // so if (free(in/out)) returns false only the first time!
174
+ param_holder = (ParamHolder*)calloc(1, sizeof(struct _ph));
175
+ return Data_Wrap_Struct(klass, 0, ta_func_free, param_holder);
176
+ }
177
+
178
+ /*
179
+ * call-seq: initialize(name)
180
+ *
181
+ * Create new instance of technical analysis function with given _name_.
182
+ *
183
+ */
184
+ static VALUE ta_func_initialize(VALUE self, VALUE name)
185
+ {
186
+ TA_RetCode ret_code;
187
+ const TA_FuncHandle *handle;
188
+ TA_ParamHolder *ta_param_holder;
189
+ ParamHolder *param_holder;
190
+
191
+ Data_Get_Struct(self, ParamHolder, param_holder);
192
+
193
+ ret_code = TA_GetFuncHandle( RSTRING_PTR(name), &handle );
194
+ if ( ret_code == TA_SUCCESS )
195
+ {
196
+ ret_code = TA_ParamHolderAlloc( handle, &ta_param_holder );
197
+ if ( ret_code != TA_SUCCESS )
198
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_ParamHolderAlloc");
199
+ param_holder->p = ta_param_holder;
200
+ rb_iv_set(self, "@name", name);
201
+ rb_iv_set(self, "@result", rb_ary_new());
202
+ return self;
203
+ }
204
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetFuncHandle");
205
+ }
206
+
207
+ /*
208
+ * Return input parameters count.
209
+ */
210
+ static VALUE ta_func_get_input_count(VALUE self)
211
+ {
212
+ return INT2NUM((abstract_layer_get_func_info(rb_iv_get(self, "@name")))->nbInput);
213
+ }
214
+
215
+ /*
216
+ * Return option input parameters count.
217
+ */
218
+ static VALUE ta_func_get_option_input_count(VALUE self)
219
+ {
220
+ return INT2NUM((abstract_layer_get_func_info(rb_iv_get(self, "@name")))->nbOptInput);
221
+ }
222
+
223
+ /*
224
+ * Return output parameters count.
225
+ */
226
+ static VALUE ta_func_get_output_count(VALUE self)
227
+ {
228
+ return INT2NUM((abstract_layer_get_func_info(rb_iv_get(self, "@name")))->nbOutput);
229
+ }
230
+
231
+ /*
232
+ * Return the list of names for technical function groups.
233
+ */
234
+ static VALUE ta_func_get_groups(VALUE self)
235
+ {
236
+ return rb_cv_get(self, "@@groups");
237
+ }
238
+
239
+ /*
240
+ * Return the hash of names for technical functions.
241
+ * The key is a name of funcion group, and value - is a list of function names.
242
+ */
243
+ static VALUE ta_func_get_functions(VALUE self)
244
+ {
245
+ return rb_cv_get(self, "@@functions");
246
+ }
247
+
248
+ /*
249
+ * call-seq: in(index)
250
+ *
251
+ * Return input parameter info for the given input parameter index.
252
+ */
253
+ static VALUE ta_func_input_param_info(VALUE self, VALUE index)
254
+ {
255
+ return ta_func_param_info(TA_INPUT_PARAM, self, rb_iv_get(self, "@name"), index);
256
+ }
257
+
258
+ /*
259
+ * call-seq: opt(index)
260
+ *
261
+ * Return option input parameter info for the given option parameter index.
262
+ */
263
+ static VALUE ta_func_option_param_info(VALUE self, VALUE index)
264
+ {
265
+ return ta_func_param_info(TA_OPTION_INPUT_PARAM, self, rb_iv_get(self, "@name"), index);
266
+ }
267
+
268
+ /*
269
+ * call-seq: out(index)
270
+ *
271
+ * Return output parameter info for the given output parameter index.
272
+ */
273
+ static VALUE ta_func_output_param_info(VALUE self, VALUE index)
274
+ {
275
+ return ta_func_param_info(TA_OUTPUT_PARAM, self, rb_iv_get(self, "@name"), index);
276
+ }
277
+
278
+ /*
279
+ * call-seq: in_int(index, array)
280
+ *
281
+ * Set input parameter (array of integer) for the given parameter index.
282
+ */
283
+ static VALUE ta_func_setup_in_integer(VALUE self, VALUE param_index, VALUE in_array)
284
+ {
285
+ TA_RetCode ret_code;
286
+ ParamHolder *param_holder;
287
+
288
+ Data_Get_Struct(self, ParamHolder, param_holder);
289
+ ret_code = TA_SetInputParamIntegerPtr( param_holder->p, FIX2INT(param_index), (int*)(RARRAY_PTR(in_array)));
290
+ if ( ret_code != TA_SUCCESS )
291
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetInputParamIntegerPtr");
292
+ }
293
+
294
+ /*
295
+ * call-seq: in_real(index, array)
296
+ *
297
+ * Set input parameter (array of real) for the given parameter index.
298
+ */
299
+ static VALUE ta_func_setup_in_real(VALUE self, VALUE param_index, VALUE in_array)
300
+ {
301
+ TA_RetCode ret_code;
302
+ ParamHolder *param_holder;
303
+
304
+ Data_Get_Struct(self, ParamHolder, param_holder);
305
+ double** dp = param_holder->in;
306
+ //FIXME: memory leak fixed: johnribera@hotmail.com (see: FL2DBL())
307
+ ret_code = TA_SetInputParamRealPtr( param_holder->p, FIX2INT(param_index), FLT2DBL(&dp[FIX2INT(param_index)], in_array));
308
+ if ( ret_code != TA_SUCCESS )
309
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetInputParamRealPtr");
310
+ }
311
+
312
+ static VALUE ta_func_setup_in_price(VALUE self, VALUE param_index, VALUE in_open, VALUE in_high, VALUE in_low, VALUE in_close, VALUE in_volume, VALUE in_oi)
313
+ {
314
+ TA_RetCode ret_code;
315
+ ParamHolder *param_holder;
316
+ Data_Get_Struct(self, ParamHolder, param_holder);
317
+ double **dp = param_holder->in;
318
+
319
+ ret_code = TA_SetInputParamPricePtr(
320
+ param_holder->p,
321
+ FIX2INT(param_index),
322
+ FLT2DBL(&dp[0], in_open),
323
+ FLT2DBL(&dp[1], in_high),
324
+ FLT2DBL(&dp[2], in_low),
325
+ FLT2DBL(&dp[3], in_close),
326
+ FLT2DBL(&dp[4], in_volume),
327
+ FLT2DBL(&dp[5], in_oi));
328
+ if ( ret_code != TA_SUCCESS )
329
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetInputParamPricePtr");
330
+ }
331
+
332
+ /*
333
+ * call-seq: opt_int(index, value)
334
+ *
335
+ * Set option parameter (integer) for the given parameter index.
336
+ */
337
+ static VALUE ta_func_setup_opt_in_integer(VALUE self, VALUE param_index, VALUE val)
338
+ {
339
+ TA_RetCode ret_code;
340
+ ParamHolder *param_holder;
341
+ Data_Get_Struct(self, ParamHolder, param_holder);
342
+ ret_code = TA_SetOptInputParamInteger( param_holder->p, FIX2INT(param_index), FIX2INT(val));
343
+ if ( ret_code != TA_SUCCESS )
344
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetOptInputParamIntegerPtr");
345
+ }
346
+
347
+ /*
348
+ * call-seq: opt_real(index, value)
349
+ *
350
+ * Set option parameter (real) for the given parameter index.
351
+ */
352
+ static VALUE ta_func_setup_opt_in_real(VALUE self, VALUE param_index, VALUE val)
353
+ {
354
+ TA_RetCode ret_code;
355
+ ParamHolder *param_holder;
356
+
357
+ Data_Get_Struct(self, ParamHolder, param_holder);
358
+ ret_code = TA_SetOptInputParamReal( param_holder->p, FIX2INT(param_index), NUM2DBL(val));
359
+ if ( ret_code != TA_SUCCESS )
360
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetOptInputParamRealPtr");
361
+ }
362
+
363
+ /*
364
+ * call-seq: out_real(index, array)
365
+ *
366
+ * Set output parameter (array of real) for the given parameter index.
367
+ */
368
+ static VALUE ta_func_setup_out_real(VALUE self, VALUE param_index, VALUE out_array)
369
+ {
370
+ TA_RetCode ret_code;
371
+ ParamHolder *param_holder;
372
+ long idx = FIX2INT(param_index);
373
+ if (idx > 2)
374
+ rb_raise(rb_eRuntimeError, "param_index must be 0..2");
375
+ Data_Get_Struct(self, ParamHolder, param_holder);
376
+ rb_ary_store(rb_iv_get(self, "@result"), idx, out_array);
377
+ // FIXME: malloc w/o free: johnribera@hotmail.com fixed
378
+ double **dp = &(param_holder->out[idx]);
379
+ if (*dp) free(*dp); // not true only 1st time called (reusing same ptrs)
380
+ *dp = (double*)malloc(RARRAY_LEN(out_array) * sizeof(double));
381
+ ret_code = TA_SetOutputParamRealPtr(param_holder->p, idx, *dp);
382
+ if ( ret_code != TA_SUCCESS )
383
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetOutputParamRealPtr");
384
+ }
385
+
386
+ static VALUE ta_func_setup_out_integer(VALUE self, VALUE param_index, VALUE out_array)
387
+ {
388
+ TA_RetCode ret_code;
389
+ ParamHolder *param_holder;
390
+ long idx = FIX2INT(param_index);
391
+ if (idx > 2)
392
+ rb_raise(rb_eRuntimeError, "param_index must be 0..2");
393
+ Data_Get_Struct(self, ParamHolder, param_holder);
394
+ rb_ary_store(rb_iv_get(self, "@result"), idx, out_array);
395
+ // FIXME: malloc w/o free FIXED: johnribera@Hotmail.com
396
+ int **ip = (int**)&(param_holder->out[idx]);
397
+ if (*ip) free(*ip); // not true only very 1st time in
398
+ *ip = (int*)malloc(RARRAY_LEN(out_array) * sizeof(int));
399
+ ret_code=TA_SetOutputParamIntegerPtr( param_holder->p, idx, *ip);
400
+ if ( ret_code != TA_SUCCESS )
401
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_SetOutputParamIntegerPtr");
402
+ }
403
+
404
+ /*
405
+ * call-seq: call(in_start, in_end)
406
+ *
407
+ * Call technical function with input data from in_start..in_end.
408
+ */
409
+ static VALUE ta_func_call(VALUE self, VALUE in_start, VALUE in_end)
410
+ {
411
+ TA_RetCode ret_code;
412
+ ParamHolder *param_holder;
413
+ TA_Integer out_start, out_num;
414
+ VALUE ary, sub_ary;
415
+ int i,j;
416
+
417
+ Data_Get_Struct(self, ParamHolder, param_holder);
418
+ ret_code = TA_CallFunc( param_holder->p, FIX2INT(in_start), FIX2INT(in_end), &out_start, &out_num);
419
+ if ( ret_code != TA_SUCCESS )
420
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_CallFunc");
421
+ ary = rb_iv_get(self, "@result");
422
+ for (i = 0; i<RARRAY_LEN(ary); i++)
423
+ if (TYPE(rb_ary_entry(ary, i)) == T_ARRAY)
424
+ {
425
+ sub_ary = rb_ary_entry(ary, i);
426
+ for (j=0; j<out_num; j++)
427
+ {
428
+ double el = ((double*)param_holder->out[i])[j];
429
+ rb_ary_store(sub_ary, j+out_start, rb_float_new(el));
430
+ }
431
+ }
432
+ return rb_ary_new3(2, INT2FIX(out_start), INT2FIX(out_num));
433
+ }
434
+
435
+ static VALUE ta_func_lookback(VALUE self)
436
+ {
437
+ TA_RetCode ret_code;
438
+ ParamHolder *param_holder;
439
+ TA_Integer out_lookback;
440
+
441
+ Data_Get_Struct(self, ParamHolder, param_holder);
442
+ ret_code = TA_GetLookback(param_holder->p, &out_lookback);
443
+ if ( ret_code != TA_SUCCESS )
444
+ rb_raise(rb_eRuntimeError, "unsuccess return code TA_GetLookback");
445
+
446
+ return INT2FIX(out_lookback);
447
+ }
448
+
449
+ void Init_talib()
450
+ {
451
+
452
+ /*
453
+ * Ruby extension for technical functions library api.
454
+ */
455
+ rb_mTaLib = rb_define_module("TaLib");
456
+
457
+ rb_define_const(rb_mTaLib, "TA_Input_Price", INT2FIX(TA_Input_Price));
458
+ rb_define_const(rb_mTaLib, "TA_Input_Real", INT2FIX(TA_Input_Real));
459
+ rb_define_const(rb_mTaLib, "TA_Input_Integer", INT2FIX(TA_Input_Integer));
460
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_OPEN", INT2FIX(TA_IN_PRICE_OPEN));
461
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_HIGH", INT2FIX(TA_IN_PRICE_HIGH));
462
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_LOW", INT2FIX(TA_IN_PRICE_LOW));
463
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_CLOSE", INT2FIX(TA_IN_PRICE_CLOSE));
464
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_VOLUME", INT2FIX(TA_IN_PRICE_VOLUME));
465
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_OPENINTEREST", INT2FIX(TA_IN_PRICE_OPENINTEREST));
466
+ rb_define_const(rb_mTaLib, "TA_IN_PRICE_TIMESTAMP", INT2FIX(TA_IN_PRICE_TIMESTAMP));
467
+ rb_define_const(rb_mTaLib, "TA_OptInput_RealRange", INT2FIX(TA_OptInput_RealRange));
468
+ rb_define_const(rb_mTaLib, "TA_OptInput_RealList", INT2FIX(TA_OptInput_RealList));
469
+ rb_define_const(rb_mTaLib, "TA_OptInput_IntegerRange", INT2FIX(TA_OptInput_IntegerRange));
470
+ rb_define_const(rb_mTaLib, "TA_OptInput_IntegerList", INT2FIX(TA_OptInput_IntegerList));
471
+ rb_define_const(rb_mTaLib, "TA_OPTIN_IS_PERCENT", INT2FIX(TA_OPTIN_IS_PERCENT));
472
+ rb_define_const(rb_mTaLib, "TA_OPTIN_IS_DEGREE", INT2FIX(TA_OPTIN_IS_DEGREE));
473
+ rb_define_const(rb_mTaLib, "TA_OPTIN_IS_CURRENCY", INT2FIX(TA_OPTIN_IS_CURRENCY));
474
+ rb_define_const(rb_mTaLib, "TA_OPTIN_ADVANCED", INT2FIX(TA_OPTIN_ADVANCED));
475
+ rb_define_const(rb_mTaLib, "TA_Output_Real", INT2FIX(TA_Output_Real));
476
+ rb_define_const(rb_mTaLib, "TA_Output_Integer", INT2FIX(TA_Output_Integer));
477
+ rb_define_const(rb_mTaLib, "TA_OUT_LINE", INT2FIX(TA_OUT_LINE));
478
+ rb_define_const(rb_mTaLib, "TA_OUT_DOT_LINE", INT2FIX(TA_OUT_DOT_LINE));
479
+ rb_define_const(rb_mTaLib, "TA_OUT_DASH_LINE", INT2FIX(TA_OUT_DASH_LINE));
480
+ rb_define_const(rb_mTaLib, "TA_OUT_DOT", INT2FIX(TA_OUT_DOT));
481
+ rb_define_const(rb_mTaLib, "TA_OUT_HISTO", INT2FIX(TA_OUT_HISTO));
482
+ rb_define_const(rb_mTaLib, "TA_OUT_PATTERN_BOOL", INT2FIX(TA_OUT_PATTERN_BOOL));
483
+ rb_define_const(rb_mTaLib, "TA_OUT_PATTERN_BULL_BEAR", INT2FIX(TA_OUT_PATTERN_BULL_BEAR));
484
+ rb_define_const(rb_mTaLib, "TA_OUT_PATTERN_STRENGTH", INT2FIX(TA_OUT_PATTERN_STRENGTH));
485
+ rb_define_const(rb_mTaLib, "TA_OUT_POSITIVE", INT2FIX(TA_OUT_POSITIVE));
486
+ rb_define_const(rb_mTaLib, "TA_OUT_NEGATIVE", INT2FIX(TA_OUT_NEGATIVE));
487
+ rb_define_const(rb_mTaLib, "TA_OUT_ZERO", INT2FIX(TA_OUT_ZERO));
488
+ rb_define_const(rb_mTaLib, "TA_OUT_UPPER_LIMIT", INT2FIX(TA_OUT_UPPER_LIMIT));
489
+ rb_define_const(rb_mTaLib, "TA_OUT_LOWER_LIMIT", INT2FIX(TA_OUT_LOWER_LIMIT));
490
+ rb_define_const(rb_mTaLib, "TA_MAType_SMA", INT2FIX((int)(TA_MAType_SMA)));
491
+ rb_define_const(rb_mTaLib, "TA_MAType_EMA", INT2FIX((int)(TA_MAType_EMA)));
492
+ rb_define_const(rb_mTaLib, "TA_MAType_WMA", INT2FIX((int)(TA_MAType_WMA)));
493
+ rb_define_const(rb_mTaLib, "TA_MAType_DEMA", INT2FIX((int)(TA_MAType_DEMA)));
494
+ rb_define_const(rb_mTaLib, "TA_MAType_TEMA", INT2FIX((int)(TA_MAType_TEMA)));
495
+ rb_define_const(rb_mTaLib, "TA_MAType_TRIMA", INT2FIX((int)(TA_MAType_TRIMA)));
496
+ rb_define_const(rb_mTaLib, "TA_MAType_KAMA", INT2FIX((int)(TA_MAType_KAMA)));
497
+ rb_define_const(rb_mTaLib, "TA_MAType_MAMA", INT2FIX((int)(TA_MAType_MAMA)));
498
+ rb_define_const(rb_mTaLib, "TA_MAType_T3", INT2FIX((int)(TA_MAType_T3)));
499
+
500
+ rb_struct_define("TA_RealRange", "min", "max", "precision", NULL);
501
+ rb_struct_define("TA_IntegerRange", "min", "max", NULL );
502
+ rb_struct_define("TA_RealDataPair", "value", "string", NULL );
503
+ rb_struct_define("TA_IntegerDataPair", "value", "string", NULL );
504
+ rb_struct_define("TA_RealList", "data", "nb_element", NULL );
505
+ rb_struct_define("TA_IntegerList", "data", "nb_element", NULL );
506
+
507
+ rb_sInParamInfo = rb_struct_define("TA_InputParameterInfo", "type", "param_name", "flags", NULL );
508
+ rb_sOptInParamInfo = rb_struct_define("TA_OutInputParameterInfo", "type", "param_name", "flags", "display_name", "data_set", "default_value", "hint", "help_file", NULL );
509
+ rb_sOutParamInfo = rb_struct_define("TA_OutputParameterInfo", "type", "param_name", "flags", NULL );
510
+
511
+ /*
512
+ * Class for technical analysis function.
513
+ */
514
+ rb_cTAFunction = rb_define_class_under(rb_mTaLib, "Function", rb_cObject);
515
+ rb_define_alloc_func(rb_cTAFunction, ta_func_alloc);
516
+ rb_define_method(rb_cTAFunction, "initialize", ta_func_initialize, 1);
517
+ rb_define_attr(rb_cTAFunction, "result", 1, 1);
518
+
519
+ rb_define_module_function( rb_cTAFunction, "groups", ta_func_get_groups, 0 );
520
+ rb_define_module_function( rb_cTAFunction, "functions", ta_func_get_functions, 0 );
521
+
522
+ rb_define_method( rb_cTAFunction, "ins", ta_func_get_input_count, 0 );
523
+ rb_define_method( rb_cTAFunction, "outs", ta_func_get_output_count, 0 );
524
+ rb_define_method( rb_cTAFunction, "opts", ta_func_get_option_input_count, 0 );
525
+
526
+ rb_define_method( rb_cTAFunction, "in", ta_func_input_param_info, 1);
527
+ rb_define_method( rb_cTAFunction, "opt", ta_func_option_param_info, 1);
528
+ rb_define_method( rb_cTAFunction, "out", ta_func_output_param_info, 1);
529
+
530
+ rb_define_method( rb_cTAFunction, "in_int", ta_func_setup_in_integer, 2);
531
+ rb_define_method( rb_cTAFunction, "in_real", ta_func_setup_in_real, 2);
532
+ rb_define_method( rb_cTAFunction, "in_price", ta_func_setup_in_price, 7);
533
+ rb_define_method( rb_cTAFunction, "opt_int", ta_func_setup_opt_in_integer, 2);
534
+ rb_define_method( rb_cTAFunction, "opt_real", ta_func_setup_opt_in_real, 2);
535
+ rb_define_method( rb_cTAFunction, "out_int", ta_func_setup_out_integer, 2);
536
+ rb_define_method( rb_cTAFunction, "out_real", ta_func_setup_out_real, 2);
537
+
538
+ rb_define_method( rb_cTAFunction, "lookback", ta_func_lookback, 0);
539
+ rb_define_method( rb_cTAFunction, "call", ta_func_call, 2);
540
+ }
data/lib/talib_ruby.rb ADDED
@@ -0,0 +1,9 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ #require File.dirname(__FILE__) + '/../ext/talib/talib'
5
+ require 'talib'
6
+
7
+ module TalibRuby
8
+ VERSION = '0.0.4'
9
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: talib_ruby
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 4
10
+ version: 1.0.4
11
+ platform: ruby
12
+ authors:
13
+ - Valentin Treu
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-22 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Ruby Wrapper for the Technical Analysis Library ta-lib
23
+ email: rivella50@gmail.com
24
+ executables: []
25
+
26
+ extensions:
27
+ - ext/talib/extconf.rb
28
+ - ext/talib/extconf.rb
29
+ extra_rdoc_files:
30
+ - README.textile
31
+ files:
32
+ - example/ma.rb
33
+ - ext/talib/talib.c
34
+ - lib/talib_ruby.rb
35
+ - README.textile
36
+ - ext/talib/extconf.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/rivella50/talib-ruby
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ hash: 3
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.7
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Ruby Wrapper for ta-lib
71
+ test_files: []
72
+