ROOT_Application  2.0
C++ Core modules and GUIStock
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TAlibAPI.cpp
Go to the documentation of this file.
1 
8 #include "TAlibAPI.h"
9 #include "ListDataStock.h"
10 
11 #include "TALibException.h"
12 #include "../utils/Indicator.h"
13 
14 #include <algorithm>
15 using namespace std;
16 
19 #ifdef DEBUG_TALIB
20  cout << "Constructor TAlibAPI " << endl;
21 #endif
22  // associate the resource, res_ptr is a shared pointer
23  res_ptr = TAResource::CreateResource();
24 
25 #ifdef DEBUG_TALIB
26  cout << "res_ptr.use_count() " << res_ptr.use_count() << endl;
27  cout << "res_ptr " << res_ptr << endl;
28 #endif
29 }
30 
32 #ifdef DEBUG_TALIB
33  cout << "Destructor TAlibAPI " << endl;
34  // not updated yet
35  cout << "res_ptr use_count() " << res_ptr.use_count() << endl;
36 #endif
37  // res_ptr is deleted, but not necessarely the ressource
38 }
39 
42 {
43 #ifdef DEBUG_TALIB
44  std::cout << "TAResource init()" << std::endl;
45 #endif
46 
47  TA_RetCode rc = TA_Initialize();
48  if ( rc == TA_SUCCESS ) {
49 #ifdef DEBUG_TALIB
50  std::cout << "Ok TA_Initialize" << std::endl;
51 #endif
52  return true;
53 
54  } else {
55  std::cout << "Error in TA_Initialize: " << rc << std::endl;
56  return false;
57  }
58 }
59 
61 {
62 #ifdef DEBUG_TALIB
63  std::cout << "TAResource Shutdown()" << endl;
64 #endif
65 
66  TA_RetCode rc = TA_Shutdown();
67  if (rc != TA_SUCCESS) {
68  std::cout << "TALib Error on TA_Shutdown" << rc << std::endl;
69  return false;
70 
71  } else {
72 #ifdef DEBUG_TALIB
73  std::cout << "Ok TALIB TA_Shutdown properly" << std::endl;
74 #endif
75  return true;
76  }
77 }
78 
80 {
81 #ifdef DEBUG_TALIB
82  cout << "Constructor TAResource, init TAlib" << endl;
83 #endif
84  TAResource::Init();
85 }
86 
88 {
89 #ifdef DEBUG_TALIB
90  cout << "Destructor TAResource" << endl;
91 #endif
92  TAResource::Shutdown();
93 }
94 
95 // maybe not thread-safe mutex to add. Phoenix working
96 std::shared_ptr<TAlibAPI::TAResource> TAlibAPI::TAResource::CreateResource()
97 {
98 #ifdef DEBUG_TALIB
99  cout << "TAResource CreateResource " << endl;
100 #endif
101  // cannot do this
102  // http://stackoverflow.com/questions/19147588/shared-pointers-to-a-singleton-do-not-recognize-each-other
103  //static TARessource instance;
104  //return TAResPtr( instance );
105 
106  // first solution, but get use_count == 2 after and never delete. It seems they point to different object
107  //static TAResPtr instance = std::make_shared<TARessource>();
108  //cout << "instance.use_count() " << instance.use_count() << endl;
109  //return instance;
110 
111  // second solution, weak pointer does not increase the counter, need lock to convert to shared_ptr
112  // keep a static weak pointer, same instance for different call
113  static std::weak_ptr<TAResource> instance;
114 
115  // uncomment (a) (b) for thread-safe
116  //static std::mutex mutex; // (a)
117  //const std::lock_guard< std::mutex > lock( mutex ); // (b)
118  // Lock convert a weak_ptr into a shared_ptr, or nullptr, it has to be copied into a shared_ptr before usage
119  if( const auto result = instance.lock() ) return result;
120 
121  // case nullptr create (or recreate) the object, same use lock
122  // here need tricks to get private constructor, destructor private
123  // http://stackoverflow.com/questions/8147027/how-do-i-call-stdmake-shared-on-a-class-with-only-protected-or-private-const
124  //return ( instance = std::make_shared<TAResource>() ).lock();
125 
126  // still needs public destructor
127  return ( instance = std::shared_ptr<TAResource>( new TAResource() ) ).lock();
128 }
129 
130 // idea vector for input CSV and volume, always send vec<ListDataBase *>
131 //
132 // Main entry for running a computation with TAlib, should be the only public function
133 // Will transform Lists to to C Array, always chronological order for computation
134 // and fill the ldata_out...in...the correct order
135 //
136 // Need to add tmscl for dynamic_cast or test if dynamic_cast works or return nullptr.
137 // Timescale present in input/output lists.
138 bool TAlibAPI::Compute( const ETime tmscl, const Indicator new_indic, const std::vector<int>& vec_param,
139  const std::vector< ListDataStockBase *>& vec_ldata_in, ListDataStockBase *ldata_out) const
140  throw (TALibException)
141 {
142 #ifdef DEBUG_TALIB
143  std::cout << "\nEntry TALib::Compute new_indic " << new_indic.label() << std::endl;
144  std::cout << "Name of out " << ldata_out->GetName() << " " << ldata_out->Capacity() << std::endl;
145  //std::cout << "size of vec_ldata_in " << vec_ldata_in.size() << std::endl;
146 #endif
147 
148  int retour;
149  unsigned int size_data_in;
150 
151  // array of array for input/output [list][data]
152  // could choose now, float or double
153  float **arraydata_c_in = 0;
154  // needed for a proper delete, nb of input indices
155  int nb_array_in = 0;
156  // output always double in ta-lib
157  double **arraydata_c_out = 0;
158  // nb of returned indices
159  int nb_array_out = 0;
160 
161  // value to be returned when going back to listdata
162  int offset_begin=0;
163  int out_nb_data=0;
164 
165  //always a link to dataCSV or SimpleData, always first in the vector
166  ListDataStockBase *ldata_csv_in = 0;
167  // volume needed for some indicator : AD, but never set correctly !
168  ListDataStockBase *ldata_volume_in = 0;
169 
170  // assign ldata_csv to the first list input, and get size of the input
171  // always CSV/INST then Volume ?
172 #ifdef DEBUG_TALIB
173  std::cout << "Size vec_ldata_in " << vec_ldata_in.size() << std::endl;
174 #endif
175  if ( vec_ldata_in.size() >= 1 ) {
176 
177  // CSV always first and gives the size
178  ldata_csv_in = vec_ldata_in[0];
179  //ldata_csv_in = dynamic_cast<ldata_candle *>(vec_ldata_in[0]);
180  size_data_in = (unsigned int) ldata_csv_in->GetSize();
181 
182  // add new, if two in input it is the volume
183  if ( vec_ldata_in.size() >= 2 ) {
184  ldata_volume_in = vec_ldata_in[1];
185  std::cout << "Volume is present as input " << std::endl;
186  }
187 
188  } else {
189  std::cout << "Error in size of vec_ldata_in in TAlibAPI::Compute, throw Exception" << std::endl;
190  throw ( TALibException( new_indic, vec_param, "TALibException: Size of Lists input is null") );
191  }
192 
193  //make creation of array for general purpose
194  // can also get this info from TA_FuncInfo
195  nb_array_in = new_indic.nb_input();
196  nb_array_out = new_indic.nb_output();
197 #ifdef DEBUG_TALIB
198  std::cout << "nb array in/out " << nb_array_in << " " << nb_array_out << std::endl;
199 #endif
200 
201  // can add a test if max vec_param > size will be problems, or let exception
202  if ( (unsigned int)*std::max_element(vec_param.cbegin(), vec_param.cend()) > size_data_in )
203  throw TALibException( new_indic, vec_param, "Size of the input data is too small for theses parameters");
204 
205  // allocate memory for output, always double fom TA-lib
206  // test if > 0, maybe in some case...
207  arraydata_c_out = new double*[ nb_array_out ];
208  for ( int i = 0; i< nb_array_out; i++ ) {
209  arraydata_c_out[i] = new double[size_data_in];
210  //init all to zero, not needed
211  for ( unsigned int j = 0; j < size_data_in; j++ )
212  arraydata_c_out[i][j] = 0.;
213  }
214 
215  //allocate nb_array_in, size could be allocated in GetCArray with initalizer list as well
216  arraydata_c_in = new float*[ nb_array_in ];
217 
218  // case with 3 outputs, 1 entry
219  if ( ( new_indic.label().compare("MACD") == 0 ) || ( new_indic.label().compare("BOLL") == 0 ) ||
220  ( new_indic == Indicator::RSI ) || ( new_indic.label().compare("STOCHF") == 0 ) ) {
221 
222 #ifdef DEBUG_TALIB
223  std::cout << "Compute MACD/BOLL/STOCHF/RSI: " << new_indic.label() << std::endl;
224  // RSI only one param
225  //std::cout << "param " << " vec_param " << vec_param[0] << " " << vec_param[1] << std::endl;//" " << vec_param[2] << std::endl;
226 #endif
227  // fill the inpput array, method of ListDataStock, will make chronologic for TAlib
228  if ( ( new_indic == Indicator::MACD ) || ( new_indic == Indicator::BOLL ) || ( new_indic == Indicator::RSI ) ) {
229 
230  //ldata_csv_in->GetCArray( &(arraydata_c_in[0]), "Close");
231  if ( tmscl == ETime::INST )
232  //ldata_csv_in->GetCArray( &(arraydata_c_in[0]), "Close");
233  //(dynamic_cast<ldata_dcsv *>(ldata_csv_in))->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, 0 );
234  ldata_csv_in->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, 0 );
235  else
236  //(dynamic_cast<ldata_candle *>(ldata_csv_in))->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, as_uint( EDS::ECSV::CLOSE ));
237  ldata_csv_in->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, as_uint( EDS::ECSV::CLOSE ));
238 
239  // case STOCHF, need more entry, but only CSV. Not possible with INST.
240  } else if ( new_indic == Indicator::STOCHF ) {
241 #ifdef DEBUG_TALIB
242  std::cout << "new indic STOCHF nb_array_int" << nb_array_in << std::endl;
243 #endif
244  if ( tmscl == ETime::INST )
245  throw TALibException( new_indic, vec_param, "Cannot compute STOCHF with a TimeScale INST");
246 
247  ldata_csv_in->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, as_uint( EDS::ECSV::HIGH) );
248  ldata_csv_in->GetCArray( &(arraydata_c_in[1]), EPChrono::CHRONO, as_uint( EDS::ECSV::LOW) );
249  ldata_csv_in->GetCArray( &(arraydata_c_in[2]), EPChrono::CHRONO, as_uint( EDS::ECSV::CLOSE) );
250 
251 
252  // error
253  } else {
254  std::cout << "\n\tCompute indicator not implemented !!\n" << std::endl;
255  throw TALibException( new_indic, vec_param, "Indicator no implemented");
256  }
257 
258  retour = ComputeMACD ( arraydata_c_in ,size_data_in, new_indic.label(),
259  vec_param, arraydata_c_out, nb_array_out, offset_begin, out_nb_data);
260 #ifdef DEBUG_TALIB
261  std::cout << "\n\tRetour ComputeMACD" << std::endl;
262  std::cout << "out_nb_data " << out_nb_data << " offset_begin " << offset_begin << std::endl;
263  std::cout << "arraydata_c_out " << arraydata_c_out[0][0] << " " << arraydata_c_out[1][0] << " " << arraydata_c_out[2][0] << std::endl;
264  std::cout << "arraydata_c_out " << arraydata_c_out[0][1] << " " << arraydata_c_out[1][1] << " " << arraydata_c_out[2][1] << std::endl;
265  //std::cout << "arraydata_c_out[23] " << arraydata_c_out[0][23] << " " << arraydata_c_out[1][23] << " " << arraydata_c_out[2][23] << std::endl;
266 #endif
267 
268  } // End MACD/RSI
269 
270  // Case SMA, EMA, WMA, can be computed for INST
271  else if ( new_indic.label().compare(1,2,"MA",0,2) == 0 ) {
272 #ifdef DEBUG_TALIB
273  std::cout << "Compute a MA: " << new_indic.label() << std::endl;
274  //std::cout << " size_data_in: " << ldata_csv_in->GetSize() << std::endl;
275 #endif
276 
277  // Can compute XMA with CSV or INST
278  if ( tmscl == ETime::INST )
279  //ldata_csv_in->GetCArray( &(arraydata_c_in[0]), "Close");
280  ldata_csv_in->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, 0 );
281  else
282  ldata_csv_in->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, as_uint( EDS::ECSV::CLOSE ));
283 
284 /*
285  std::cout << "After copy in TAlib" << std::endl;
286  for (int j=0;j<ldata_csv_in->GetSize();j++)
287  std::cout << arraydata_c_in[0][j] << std::endl;
288 
289  std::cout << "&arraydata_c_in " << &arraydata_c_in << std::endl;
290  std::cout << "arraydata_c_in " << arraydata_c_in << std::endl;
291  std::cout << "arraydata_c_in[0] " << arraydata_c_in[0] << std::endl;
292  std::cout << "&arraydata_c_in[0] " << &(arraydata_c_in[0]) << std::endl;
293 */
294  retour = ComputeMA ( arraydata_c_in ,size_data_in, new_indic.label(),
295  vec_param[0], arraydata_c_out, offset_begin, out_nb_data);
296 #ifdef DEBUG_TALIB
297  std::cout << "offset begin " << offset_begin << std::endl;
298 #endif
299 
300 
301  //case use volume and no parameter.
302  } else if ( new_indic == Indicator::AD ) {
303 #ifdef DEBUG_TALIB
304  std::cout << "In TAlib::Compute Compute AD " << std::endl;
305  std::cout << "new indic AD nb_array_in " << nb_array_in << std::endl;
306 #endif
307 
308  if ( tmscl == ETime::INST )
309  throw TALibException( new_indic, vec_param, "Cannot compute AD with a TimeScale INST");
310 
311  // fill input array
312  ldata_csv_in->GetCArray( &(arraydata_c_in[0]), EPChrono::CHRONO, as_uint( EDS::ECSV::HIGH) );
313  ldata_csv_in->GetCArray( &(arraydata_c_in[1]), EPChrono::CHRONO, as_uint( EDS::ECSV::LOW) );
314  ldata_csv_in->GetCArray( &(arraydata_c_in[2]), EPChrono::CHRONO, as_uint( EDS::ECSV::CLOSE) );
315  ldata_volume_in->GetCArray( &(arraydata_c_in[3]), EPChrono::CHRONO, 0 );
316  retour = ComputeMACD ( arraydata_c_in ,size_data_in, new_indic.label(),
317  vec_param, arraydata_c_out, nb_array_out, offset_begin, out_nb_data);
318  }
319 
320  else {
321  std::cout << "Not found this indicator in computeTA " << std::endl;
322  throw TALibException( new_indic, vec_param, "Indicator no implemented");
323  }
324 
325  //Check if retour is ok, ComputeX does not throw exception
326  if (!retour) {
327 #ifdef DEBUG_TALIB
328  std::cout << "Ok for ComputeMA or other offset_begin " << offset_begin << " copy back data " << std::endl;
329  std::cout << "Call PutCArray nb_array_out " << nb_array_out << std::endl;
330 #endif
331 
332  // Fill ldata_out with results, works for all ListdataStock
333  ldata_out->PutCArray( *ldata_csv_in, out_nb_data, nb_array_out, arraydata_c_out,
334  offset_begin, 0, EPChrono::CHRONO, false );
335  //std::cout << "return PutCArray = 0" << std::endl;
336 
337  } else {
338 #ifdef DEBUG_CPP
339  std::cout << "Error in computation, delete the listdatastock " << std::endl;
340 #endif
341 
342  // why error appears now ,not before ? did not test well valgrind ?
343  for ( int i = 0; i< nb_array_in; i++ ) {
344  delete[] arraydata_c_in[i];
345  }
346  delete[] arraydata_c_in; arraydata_c_in = 0;
347  //std::cout << " nb_array_out " << nb_array_out << std::endl;
348  for ( int i = 0; i< nb_array_out; i++ ) {
349  delete[] arraydata_c_out[i];
350  }
351  delete[] arraydata_c_out; arraydata_c_out = 0;
352 
353  throw TALibException( new_indic, vec_param, "Error in TA-lib calculation");
354  }
355 
356  //delete temporary arrays, never called ! because of retour !
357  for ( int i = 0; i< nb_array_in; i++ ) {
358  delete[] arraydata_c_in[i];
359  }
360  delete[] arraydata_c_in; arraydata_c_in = 0;
361 
362  for ( int i = 0; i< nb_array_out; i++ ) {
363  delete[] arraydata_c_out[i];
364  }
365  delete[] arraydata_c_out; arraydata_c_out = 0;
366 
367 #ifdef DEBUG_TALIB
368  std::cout << "return from TAlib:compute ok" << std::endl;
369 #endif
370  return retour;
371 }
372 
373 int TAlibAPI::ComputeMA( float **arraydata_c_in, unsigned int size_input, std::string str_label,
374  int param, double **arraydata_c_out, int & offset_begin, int & out_nb_data) const
375 {
376 #ifdef DEBUG_TALIB
377  std::cout << "Entry ComputeMA str_label " << str_label << std::endl;
378 #endif
379  // for valgrind
380  TA_RetCode rc = TA_SUCCESS;
381  //label already exist in TA-lib, need abstract class for better
382 
383  //by default all available data
384  int startIdx=0; //index of the entry tabular to treat
385  int endIdx=size_input-1;
386 
387 #ifdef DEBUG_TALIB
388  std::cout << "startIdx " << startIdx << std::endl;
389  std::cout << "endIdx " << endIdx << std::endl;
390  std::cout << "array[0[0] " << arraydata_c_in[0][0] << std::endl;
391  std::cout << "array[0][size_input-1]" << arraydata_c_in[0][size_input-1] << std::endl;
392  std::cout << "param " << param << std::endl;
393  std::cout << "str_label " << str_label << std::endl;
394  std::cout << "arraydata_c_out[0] " << arraydata_c_out[0] << " " << arraydata_c_out[0][0] << std::endl;
395 #endif
396 
397  //test just need to change Enum MAType
398  //MAType = TA_MAType_SMA;
399 
400  if ( str_label == "SMA" ) {
401  // by default take all the data
402  // theses function use float as entry and return double
403  rc = TA_S_MA( startIdx, endIdx, arraydata_c_in[0], param,TA_MAType_SMA, &offset_begin, &out_nb_data, arraydata_c_out[0]);
404 
405  } else if ( str_label == "EMA" ) {
406  rc = TA_S_MA( startIdx, endIdx, arraydata_c_in[0], param,TA_MAType_EMA, &offset_begin, &out_nb_data, arraydata_c_out[0]);
407 
408  } else if ( str_label == "WMA" ) {
409  rc = TA_S_MA( startIdx, endIdx, arraydata_c_in[0], param,TA_MAType_WMA, &offset_begin, &out_nb_data, arraydata_c_out[0]);
410 
411  } else {
412  std::cout << "Not defined, error " << std::endl;
413  return 1;
414  }
415 
416  if (rc != TA_SUCCESS) {
417  std::cout << "error in TA_S_MA rc: " << rc << std::endl;
418  // all set to zero
419  std::cout << "offset_begin " << offset_begin <<", out_nb_data " << out_nb_data << std::endl;
420  return 1;
421  }
422  return 0;
423 }
424 
425 //make specialized for first
426 int TAlibAPI::ComputeMACD( float **arraydata_c_in, unsigned int size_input, std::string str_label,
427 std::vector<int> param, double **arraydata_c_out, unsigned int nb_array_out, int & offset_begin, int & out_nb_data ) const
428 {
429 #ifdef DEBUG_TALIB
430  std::cout << "Entry ComputeMACD str_label " << str_label << std::endl;
431  //std::cout << "param " << param[0] << " " << param[1] << " " << 3 << " " << std::endl;
432  std::cout << "size_input " << size_input << " nb_array_out " << nb_array_out << std::endl;
433 #endif
434  // init for valgrind
435  TA_RetCode rc = TA_SUCCESS;
436  int startIdx=0; //index of the entry tabular to treat
437  int endIdx=size_input-1; // 12;
438 
439 #ifdef DEBUG_TALIB
440  std::cout << "startIdx " << startIdx << std::endl;
441  std::cout << "endIdx " << endIdx << std::endl;
442 #endif
443 
444  /*
445  TA_RetCode TA_MACD( int startIdx,
446  int endIdx,
447  const double inReal[],
448  int optInFastPeriod,
449  int optInSlowPeriod,
450  int optInSignalPeriod,
451  int *outBegIdx,
452  int *outNBElement,
453  double outMACD[],
454  double outMACDSignal[],
455  double outMACDHist[] );
456  */
457  //rc = TA_MACD ( startIdx, endIdx, arraydata_c_in[0], param,TA_MAType_SMA, &offset_begin, &out_nb_data, arraydata_c_out[0]);
458  // why here const double ?? no in MA ?? (const double*) needed ? ok use S_MACD for float see /usr/local/ta-lib/ta-lib/c/include/ta_func.h
459 
460  if ( str_label.compare("MACD") == 0 ) {
461 #ifdef DEBUG_TALIB
462  std::cout << "Compute MACD " << std::endl;
463 #endif
464  rc = TA_S_MACD ( startIdx, endIdx, arraydata_c_in[0], param[0], param[1], param[2], &offset_begin, &out_nb_data,
465  arraydata_c_out[0], arraydata_c_out[1], arraydata_c_out[2] );
466  } else if ( str_label.compare("BOLL") == 0 ) {
467 #ifdef DEBUG_TALIB
468  std::cout << "Compute BOLL " << std::endl;
469 #endif
470  rc = TA_S_BBANDS ( startIdx, endIdx, arraydata_c_in[0], param[0], (double)param[1], (double)param[2], TA_MAType_SMA,
471  &offset_begin, &out_nb_data,
472  arraydata_c_out[0], arraydata_c_out[1], arraydata_c_out[2] );
473 
474  } else if ( str_label.compare("STOCHF") == 0 ) {
475 #ifdef DEBUG_TALIB
476  std::cout << "Compute STOCHF" << std::endl;
477 #endif
478  rc = TA_S_STOCHF ( startIdx, endIdx, arraydata_c_in[0], arraydata_c_in[1], arraydata_c_in[2], param[0], param[1], TA_MAType_SMA,
479  &offset_begin, &out_nb_data, arraydata_c_out[0], arraydata_c_out[1] );
480 
481  } else if ( str_label.compare("RSI") == 0 ) {
482 #ifdef DEBUG_TALIB
483  std::cout << "Compute RSI" << std::endl;
484 #endif
485  rc = TA_S_RSI ( startIdx, endIdx, arraydata_c_in[0], param[0],
486  &offset_begin, &out_nb_data, arraydata_c_out[0] );
487 
488  } else if ( str_label.compare("AD") == 0 ) {
489 #ifdef DEBUG_TALIB
490  std::cout << "TAlib::ComputeMACD Compute AD" << std::endl;
491 #endif
492  rc = TA_S_AD ( startIdx, endIdx, arraydata_c_in[0], arraydata_c_in[1], arraydata_c_in[2], arraydata_c_in[3],
493  &offset_begin, &out_nb_data, arraydata_c_out[0] );
494  //else error
495  } else {
496  std::cout << "label not known " << std::endl;
497  return 1;
498  }
499 
500 #ifdef DEBUG_TALIB
501  std::cout << "rc " << rc << std::endl;
502  std::cout << " offset " << offset_begin << " out_nb_data " << out_nb_data << std::endl;
503  //std::cout << "array[0[0] " << arraydata_c_out[0][0] << " " << arraydata_c_out[0][0] << std::endl;
504  /*
505  for ( int i=out_nb_data-1;i>=0;i--) {
506  //for ( unsigned int k=0; k< size_indic_out; k++ )
507  //tmp_vec_value[k] = (float)arraydata_c_out[k][i];
508  std::cout << "tmp_vec_value " << arraydata_c_out[0][i] << " " << arraydata_c_out[1][i] << " " << arraydata_c_out[2][i] << std::endl;
509  }
510  */
511 #endif
512 
513  if (rc != TA_SUCCESS) {
514  std::cout << "error in TA_MACD or other: " << rc << std::endl;
515  std::cout <<"offset_begin " << offset_begin <<", out_nb_data " << out_nb_data << std::endl;
516  return 1;
517  }
518  return 0;
519 }
520 
522 {
523 #ifdef DEBUG_TALIB
524  std::cout << "Entry getListFunctions " << std::endl;
525 #endif
526 
527  // could belong to the class, fill at init
528  typedef std::map< std::string, std::vector<std::string> > type_map_func;
529  typedef type_map_func::iterator it_map;
530  type_map_func map_func;
531 
532  // direct code from talib abstract.h
533  // /usr/local/ta-lib/ta-lib/c/include
534  TA_StringTable *table;
535  TA_RetCode retCode;
536  unsigned int i;
537 
538  retCode = TA_GroupTableAlloc( &table );
539 
540  if( retCode == TA_SUCCESS ) {
541  for( i=0; i < table->size; i++ )
542  //printf( "%s\n", table->string[i] );
543  map_func.insert( std::pair<std::string,
544  std::vector<std::string> >(table->string[i], std::vector<std::string>() ));
545 
546  TA_GroupTableFree( table );
547  }
548 
549  for (it_map it = map_func.begin(); it != map_func.end(); ++it ) {
550 
551  retCode = TA_FuncTableAlloc( ((*it).first).c_str(), &table );
552 
553  if( retCode == TA_SUCCESS ) {
554  for( i=0; i < table->size; i++ )
555  //printf( "%s\n", table->string[i] );
556  (*it).second.push_back( table->string[i] );
557 
558  TA_FuncTableFree( table );
559  }
560 
561  //std::cout << "Group " << (*it).first << std::endl;
562  }
563  //std::cout
564 
565  for (it_map it = map_func.begin(); it != map_func.end(); ++it ) {
566 
567  std::cout << "Group " << (*it).first << std::endl;
568  std::vector<std::string>::iterator it_v;
569  for ( it_v = (*it).second.begin(); it_v != (*it).second.end(); ++it_v ) {
570  std::cout << " " << *it_v << std::endl;
571  }
572  }
573 
574  const TA_FuncHandle *handle;
575  const TA_FuncInfo *theInfo;
576 
577  retCode = TA_GetFuncHandle( "CDL2CROWS", &handle );
578 
579  if( retCode == TA_SUCCESS ) {
580  retCode = TA_GetFuncInfo( handle, &theInfo );
581  if( retCode == TA_SUCCESS ) {
582  printf( "Nb Input = %d\n", theInfo->nbInput );
583  printf( "flags = %d\n", theInfo->flags );
584  //if ( theInfo->flags == TA_FUNC_FLG_CANDLESTICK ) {
585 
586  if ( theInfo->flags & TA_FUNC_FLG_CANDLESTICK ) {
587  std::cout << "I am a CandleStick " << std::endl;
588  } else {
589  std::cout << "I am not a CandleStick " << std::endl;
590  }
591 
592  if ( theInfo->flags == TA_FUNC_FLG_OVERLAP ) {
593  std::cout << "I also scale with input " << std::endl;
594  }
595  }
596  }
597  /*
598  typedef struct TA_FuncInfo
599  {
600  // Constant information about the function. The
601  // information found in this structure is guarantee
602  // to not change at runtime.
603  //
604  const char * name;
605  const char * group;
606 
607  const char * hint; //
608  const char * camelCaseName;
609  TA_FuncFlags flags;
610 
611  unsigned int nbInput;
612  unsigned int nbOptInput;
613  unsigned int nbOutput;
614 
615  const TA_FuncHandle *handle;
616  } TA_FuncInfo;
617  */
618 
619 #ifdef DEBUG_TALIB
620  std::cout << "End GetListFunctions" << std::endl;
621 #endif
622  return;
623 }
Define a list of DataStock objects.
static Indicator const STOCHF
Definition: Indicator.h:44
TAlibAPI()
Default constructor.
Definition: TAlibAPI.cpp:18
"Clever" enumeration of the ListDataStock type : StockCSV, Volume, EMA, BOLL,...
Definition: Indicator.h:29
virtual ~TAlibAPI()
Destructor.
Definition: TAlibAPI.cpp:31
int ComputeMA(float **arraydata_c_in, unsigned int size_input, std::string str_label, int param, double **arraydata_c_out, int &offset_begin, int &out_nb_data) const
Compute Moving Averges : SMA, EMA, WMA.
Definition: TAlibAPI.cpp:373
static void GetListFunctions()
Definition: TAlibAPI.cpp:521
bool Compute(const ETime tmscl, const Indicator new_indic, const std::vector< int > &vec_param, const std::vector< ListDataStockBase * > &vec_ldata_in, ListDataStockBase *ldata_out) const
Compute an indicator.
Definition: TAlibAPI.cpp:138
static std::shared_ptr< TAResource > CreateResource()
Return a shared pointer on the current resource.
Definition: TAlibAPI.cpp:96
static Indicator const MACD
Definition: Indicator.h:44
static Indicator const AD
Definition: Indicator.h:44
static Indicator const RSI
Definition: Indicator.h:44
auto as_uint(ETime const value) -> unsigned int
Provides explicit conversion to unsigned int.
Definition: TimeScale.h:59
int ComputeMACD(float **arraydata_c_in, unsigned int size_input, std::string str_label, std::vector< int > params, double **arraydata_c_out, unsigned int nb_array_out, int &offset_begin, int &out_nb_data) const
Compute others indicators : MACD, AD, RSI, STOCHF.
Definition: TAlibAPI.cpp:426
ETime
Enumeration for the different time representation, from instantaneous (INST) to year(YEAR) ...
Definition: TimeScale.h:48
static bool Init()
Definition: TAlibAPI.cpp:41
TAResource()
Constructor made private, to force use of CreateResource()
Definition: TAlibAPI.cpp:79
Centralize all exception coming form the TALib library interface.
virtual unsigned int GetSize() const =0
Return the size of the vector.
static Indicator const BOLL
Definition: Indicator.h:44
Abstract base class for the ListDataStock, for storing base pointers in vectors.
Definition: ListDataStock.h:50
Base class for exception coming from talibapi interface.
API for using TA_lib of X in ROOT_Application.
static bool Shutdown()
Definition: TAlibAPI.cpp:60
virtual unsigned int GetCArray(var_types arraydata_c, const EPChrono b_order, const unsigned int no=0) const =0
Extract the data into a one dimensional C-array.
virtual ~TAResource()
Destructor.
Definition: TAlibAPI.cpp:87