ROOT_Application  2.0
C++ Core modules and GUIStock
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
wrapPyStock.cpp
Go to the documentation of this file.
1 
15 #ifndef Python_for_stock
16 #define Python_for_stock
17 //#include <Python.h>
18 // eclipse fine with this, but python/C API doc says it is not good !
19 #include <python2.7/Python.h>
20 #endif
21 
22 #include <cstdio>
23 #include <cstdlib>
24 #include <string>
25 #include <iostream>
26 #include <vector>
27 
28 #include "Stock.h"
29 #include "ListDataStock.h"
30 
31 // declare a c function keep as test
32 // to delete
33 int helloworld (int x)
34 {
35  /*code that does something useful*/
36  std::cout << "hello world last " << std::endl;
37  return x;
38 }
39 
41 
42 
53 // if all synchro, could read the header only, symbol must correspond, name only ?
54 // particlularly here, header is enough !!
55 // need a test boolean for reading in data_test
56 long int wrapLastCSVUpdate ( const char * symbol, bool btest ) {
57  //here to call the real C++ LastCSVUpdate
58  //use value by default, just check DAY and StockCSV
59 #ifdef DEBUG_WRAPPYSTOCK
60  std::cout << "wrapLastCVSUpdate symbol: " << symbol << std::endl;
61 #endif
62 
63  // assign the name stock
64  std::string tmp_symbol = std::string(symbol);
65 
66  time_t last_time_t=0;
68 
69  // if global to all function could be a variable of the module ?? how to do it ??
70  if ( btest == true ) {
71 #ifdef DEBUG_WRAPPYSTOCK
72  std::cout << "Set data_test mode" << std::endl;
73 #endif
75  }
76 
77  // new version use only Read_HeaderCSV, static version
78  try {
79  Stock::Read_HeaderCSV_static( tmp_symbol, ETime::DAY, dates );
80  last_time_t = dates.last;
81  } catch (StockFileError &e ) {
82  std::cout << "wrapPyStock::wrapLastCSVUpdate got exception " << std::endl;
83  // what to do here ?? should create an exception in C for Python a wrapPyStockError ?
84  return -1;
85  }
86  return (long int) last_time_t;
87 }
88 
97 static PyObject * wrap_LastCSVUpdate(PyObject *, PyObject *args) //*self, *args
98 {
99 #ifdef DEBUG_WRAPPYSTOCK
100  std::cout << "Entry wrapPyStock::wrap_LastCSVUpdate() " << std::endl;
101 #endif
102  //std::string symbol;
103  char *symbol;
104  int itest = 0;
105  bool btest = 0;
106  long int result_date;
107 
108  // ":function" use for own error processing
109  if (!PyArg_ParseTuple(args, "si:LastCVSUpdate",&symbol,&itest))
110  return NULL;
111  // got boolean from integer
112  btest = itest;
113 
114 #ifdef DEBUG_WRAPPYSTOCK
115  std::cout << "symbol " << symbol << std::endl;
116  std::cout << "btest" << btest << std::endl;
117 #endif
118 
119  result_date = wrapLastCSVUpdate( symbol, btest );
120 
121  return Py_BuildValue("i",result_date);
122 }
123 
135 //
136 // called by wrap_UpdateCSV which makes translation between Python and C++ arguments and return
137 int wrapUpdateCSV (const char * symbol,std::vector<DataCSV> & new_csv,std::vector<SimpleData> & new_vol, bool btest )
138 {
139 #ifdef DEBUG_WRAPPYSTOCK
140  std::cout << "\n\tEntry UpdateCVS in wrap: symbol " << symbol << std::endl;
141  std::cout << "btest " << btest << std::endl;
142 #endif
143 
144  std::string tmp_symbol = std::string(symbol);
145 
146  if ( btest == true ) {
147  std::cout << "Set data_test mode" << std::endl;
149  }
150 
151  Stock * stock=new Stock( tmp_symbol );
152 
153  // create temporary list, but want to associate the vector already existing
154  // important to set name StockCSV and Volume correctly, check at some points later
155  ldata_candle *new_list_csv = new ldata_candle("StockCSV", ETime::DAY ,new_csv );
156  ldata_volume *new_list_vol = new ldata_volume("Volume", ETime::DAY ,new_vol );
157 
158  // For ordering, yahoo return always no-chronological order
159  new_list_csv->Order( EPChrono::NO_CHRONO);
160  new_list_vol->Order( EPChrono::NO_CHRONO);
161 
162  //Problem of data member dates ! to delete later
163  new_list_csv->SetDates();
164  new_list_vol->SetDates();
165 #ifdef DEBUG_WRAPPYSTOCK
166  new_list_csv->PrintData();
167 #endif
168 
169 
170 
171  // Assign first the Lists to the tmp stock
172  stock->AddListDataToMap( ETime::DAY, new_list_csv);
173  stock->AddListDataToMap( ETime::DAY, new_list_vol);
174 #ifdef DEBUG_WRAPPYSTOCK
175  stock->PrintMapChrono();
176 #endif
177 
178  // Here for sure will create an other tmp_stock, could read first in this function !
179  stock->SaveCSV( ETime::DAY, btest );
180 
181  // delete stock, and associated list
182  delete stock;
183  stock=0;
184 
185  return 0;
186 }
187 
189 // wrapper, compiler say self not used ?? necessary ?? never modifed python object
190 static PyObject * wrap_hello(PyObject *, PyObject *args) //*self,args
191 {
192  int x, result;
193  if (!PyArg_ParseTuple(args, "i:hello",&x))
194  return NULL;
195  result = helloworld(x);
196  return Py_BuildValue("i",result);
197 }
198 
199 
200 
207 static PyObject * wrap_UpdateCSV(PyObject *, PyObject *args) //*self,*args
208 {
209  char *symbol;
210  // for tests, directory data_test
211  bool btest = false;
212  int itest = 0;
213 
214  int result;
215  long int size;
216  time_t date;
217  double op,pl,mo,cl;
218  double vol;
219  //float vol;
220 
221  //create object for sending to stock wrapper
222  std::vector<DataCSV> vec_csv_to_add;
223  std::vector<SimpleData> vec_vol_to_add;
224 
225  //contain List data list of list
226  PyObject *pyFullList;
227  PyObject *pyListData;
228 
229  //Extract the first tuple
230  // O means any object a list here
231  //if (!PyArg_ParseTuple(args,"sO", &symbol, &pyFullList))
232  // type int is important, not the order
233  if (!PyArg_ParseTuple(args,"sOi", &symbol, &pyFullList, &itest))
234  return NULL;
235 
236  // a priori not needed always borrowed references returned from PyArg_*
237  //Py_XINCREF(pyFullList);
238  std::cout << "parser works!!" << std::endl;
239 
240  //Check first
241  std::cout << " symbol " << symbol << std::endl;
242  if ( PyList_Check(pyFullList))
243  std::cout << "Second argument is a list" << std::endl;
244  // makes correct convertion int to bool ?
245  btest = itest;
246  std::cout << "btest " << btest << std::endl;
247  std::cout << "itest " << itest << std::endl;
248 
249 
250  size=PyList_GET_SIZE(pyFullList);
251  std::cout << "size data pyFullList " << size << std::endl;
252 
253  //create temporary object for data, will be save in the vector
254  DataCSV * data_csv = new DataCSV();
255  SimpleData * data_vol = new SimpleData();
256 
257  for (int i=0;i<size;i++)
258  {
259  // Expects PySize_t
260  // return a borrowed reference, nothing to care
261  pyListData = PyList_GET_ITEM(pyFullList,i);
262 
263  //if ( PyList_Check(pyListData))
264  // std::cout << "pyListData is a list" << std::endl;
265  date = (time_t) PyInt_AsLong(PyList_GET_ITEM(pyListData,0));
266  op = PyFloat_AsDouble(PyList_GET_ITEM(pyListData,1));
267  pl = PyFloat_AsDouble(PyList_GET_ITEM(pyListData,2));
268  mo = PyFloat_AsDouble(PyList_GET_ITEM(pyListData,3));
269  cl = PyFloat_AsDouble(PyList_GET_ITEM(pyListData,4));
270  vol = PyFloat_AsDouble(PyList_GET_ITEM(pyListData,5));
271  //std::cout << "date op " << date << " " << op << std::endl;
272 
273  //set data
274  data_csv->SetData(date,op,pl,mo,cl);
275  data_vol->SetData(date,vol);
276 
277  //copy to the vector, could make an object sur la pile pas besoin * and delete at the end
278  //like this sure to be destroyed at the end of the function
279  vec_csv_to_add.push_back(*data_csv);
280  vec_vol_to_add.push_back(*data_vol);
281 
282  //clear the object, will see missing data
283  // new function for this ?? no but overwritten anyway ?
284  //data_csv->SetData(0,0.,0.,-1000.0,0.);
285  //data_vol->SetData(0,0.);
286  }
287 
288  //can delete tmp object
289  delete data_csv;
290  data_csv=0;
291  delete data_vol;
292  data_vol=0;
293 
294  //call wrapper in C and stock
295  //std::cout << "in wrap_Update before wrapUpdateCSV" << std::endl;
296  //std::cout << "value of csv " << vec_csv_to_add[0].GetOpen() << std::endl;
297  //std::cout << "value of vol " << vec_vol_to_add[0].GetValue() << std::endl;
298 
299  result=wrapUpdateCSV(symbol, vec_csv_to_add, vec_vol_to_add, btest);
300 
301  //std::cout << "return from wrap_UpdateCSV, exit" << std::endl;
302  return Py_BuildValue("i",result);
303 }
304 
316 // note:
317 // A safe approach is to always use the generic operations (functions whose name begins with PyObject_, PyNumber_,
318 // PySequence_ or PyMapping_). These operations always increment the reference count of the object they return.
319 // This leaves the caller with the responsibility to call Py_DECREF() when they are done with the result;
320 // this soon becomes second nature.
321 
322 // "the call mechanism guarantees to hold a reference to every argument for the duration of the call."
323 // so that we do not need to care about incrementing/decrementing their use,
324 // we are sure than at least one valid reference always exist.
325 static PyObject * wrap_SaveInst(PyObject *, PyObject *args)
326 {
327 #ifdef DEBUG_WRAPPYSTOCK
328  std::cout << "Entry wrap_SaveInst " << std::endl;
329 #endif
330 
331  // local, temporary variable
332  // only a reference, should not attend to modify
333  const char *symbol;
334  PyObject *pyListData;
335  // used for test directories
336  bool btest;
337  int itest;
338 
339  time_t date;
340  float value,volume;
341  // DataStock to fill with values
342  SimpleData data_inst, data_volume;
343 
344  // function returns false AND and creates an exception, easy to catch from python caller, but from C++ ?
345  // "Note that any Python object references which are provided to the caller are borrowed references;
346  // do not decrement their reference count!"
347  if ( !PyArg_ParseTuple(args,"sOi", &symbol, &pyListData, &itest) ) {
348  // only way to generate an error is with wrong string, other cases wrong type or missing do not cause error
349  // this will throw: TypeError: function takes exactly 4 arguments (3 given)
350  //if ( !PyArg_ParseTuple(args,"sOii", &symbol, &pyListData, "itest") ) {
351  std::cout << "Error in PyArg_ParseTuple, return NULL" << std::endl;
352  return NULL;
353  }
354 
355  // convert to bool
356  btest = itest;
357 
358  assert ( PyList_Check( pyListData ) == true );
359  assert ( PyList_Size( pyListData ) == 3 );
360 
361 #ifdef DEBUG_WRAPPYSTOCK
362  std::cout << "\n parser argument" << std::endl;
363  std::cout << "symbol " << symbol << std::endl;
364  std::cout << "btest " << btest << std::endl;
365  std::cout << "PyList_Check " << PyList_Check( pyListData ) << std::endl;
366  std::cout << "length of pyListData " << PyList_Size( pyListData ) << std::endl;
367 #endif
368 
369 
370  //date = (time_t) PyInt_AsLong( PyList_GET_ITEM(pyListData, 0) );
371  date = (time_t) PyLong_AsLong( PyList_GET_ITEM(pyListData, 0) );
372  value = PyFloat_AsDouble( PyList_GET_ITEM(pyListData, 1 ) );
373  volume = PyFloat_AsDouble( PyList_GET_ITEM(pyListData, 2 ) );
374 
375  data_inst.SetData(date, value);
376  data_volume.SetData(date, volume );
377 #ifdef DEBUG_WRAPPYSTOCK
378  std::cout << "data_inst " << data_inst << std::endl;
379  std::cout << "data_volume " << data_volume << std::endl;
380 #endif
381 
382  // assign PATH_DATA_TEST if python run in test_mode
383  if ( btest == true ) {
384  std::cout << "Set data_test mode" << std::endl;
385  //Utils::SetPathData("/home/michael/workspace_kepler/ROOT_application/data_test");
387  }
388  // if test mode output (and input in this case ) in historical_tmp
389  int status = Stock::UpdateCSV_Inst( symbol, data_inst, data_volume, ETime::INST, btest );
390  if ( status != 0 ) {
391  std::cout << "DictionaryStocks::SaveInst : No data append to the file " << std::endl;
392  return Py_BuildValue("i",-1);
393  }
394 
395 
396  // correct return
397  return Py_BuildValue("i",0);
398 }
399 
400 //declare for error, not used yet
401 static PyObject *WrapError;
402 
403 //define method, python add in dictionnary sys.module name wrap
404 //first argument called by python wrapPyStoc.LastCSVUpdate
405 //second actual C function called
406 static PyMethodDef WrapMethods[] = {
407  {"hello", wrap_hello, METH_VARARGS, "Execute a print hello."},
408  {"LastCSVUpdate", wrap_LastCSVUpdate, METH_VARARGS, "Execute LastUpdate"},
409  {"UpdateCSV", wrap_UpdateCSV, METH_VARARGS, "Execute UpdateCVS"},
410  {"SaveInst", wrap_SaveInst, METH_VARARGS, "Execute SaveInst"},
411 
412  {NULL, NULL, 0, NULL} /* Sentinel */
413 };
414 
415 // MACRO defines
416 // important init{name_module} when loading in python, anyway compile...
417 // work without, both python than C ?? same valgrind problems
418 PyMODINIT_FUNC
420 {
421  PyObject *m;
422 
423  m = Py_InitModule("wrapPyStock", WrapMethods);
424  if (m == NULL)
425  return;
426 
427  // no more warning
428  //char tmp_msg[] = "wrap.error";
429  WrapError = PyErr_NewException((char *)"wrapPyStock.error", NULL, NULL);
430  Py_INCREF(WrapError);
431  PyModule_AddObject(m, "error", WrapError);
432 }
433 
434 
const std::string PATH_DATA_TEST
Important variable to adjust before compilation, should be in a configuration.
Definition: Utils.h:38
ListDataStock< DataCSV, VecChronologic > ldata_candle
Define a default policy for candlestick.
Definition: typedef.h:26
Define the class Stock to deal with an unique stock: DJ, IBM...
virtual void SetData(const time_t d, const std::vector< type_value_data > &vec)
Set a full Data : date + value(s) in a vector.
Definition: DataStock.cpp:754
int SaveCSV(const ETime tmscl, bool opt_tmp=false) const
Save Historical data to file.
Definition: Stock.cpp:1357
Define a list of DataStock objects.
int wrapUpdateCSV(const char *symbol, std::vector< DataCSV > &new_csv, std::vector< SimpleData > &new_vol, bool btest)
Uses to add data from yahoo (DAY) for StockCSV and Volume.
Specific, inherit from FileError from utils.
long int wrapLastCSVUpdate(const char *symbol, bool btest)
Get last date available from file.
Definition: wrapPyStock.cpp:56
void PrintData(const unsigned int verbose=0) const
Nice formatting output on console.
int helloworld(int x)
Definition: wrapPyStock.cpp:33
ListDataStock< SimpleData, VecChronologic > ldata_volume
Volume has also one value.
Definition: typedef.h:38
void SetPathData(std::string new_path)
forced to use this function now.
Definition: Utils.cpp:37
Use a policy PolicyChronologic, default VecNoChronologic.
static PyObject * wrap_SaveInst(PyObject *, PyObject *args)
Save instantaneous data into file.
Main class to deal with one stock.
Definition: Stock.h:56
Data type to describe Japanese candlesticks : open, high, low and close values.
Definition: DataStock.h:502
PyMODINIT_FUNC initwrapPyStock(void)
int AddListDataToMap(const ETime &tmscl, ListDataStockBase *p_listdata)
Insert a ListDataStock to the map.
Definition: Stock.cpp:622
void Order(const EPChrono b_chronologic=EPChrono::CHRONO)
Function to reverse the internal vector in its original policy.
virtual void SetData(const time_t d, const std::vector< type_value_data > &vec)
Set a full Data : date + value(s) in a vector.
Definition: DataStock.h:366
static PyObject * wrap_UpdateCSV(PyObject *, PyObject *args)
Python wrapper to Stock::wrapUpdateCSV().
static PyMethodDef WrapMethods[]
void SetDates()
Set the correct first/last dates from the DataStock in the vector.
static PyObject * wrap_hello(PyObject *, PyObject *args)
Derive class which contains only one value of type type_value_data (float or double).
Definition: DataStock.h:335
static PyObject * wrap_LastCSVUpdate(PyObject *, PyObject *args)
Get last date available from file (only DAY at this stage).
Definition: wrapPyStock.cpp:97
void PrintMapChrono(const unsigned int verbose=0) const
Print map content to the console.
Definition: Stock.cpp:2127
static SUPPRESS_NOT_USED_WARN firstlast_dates get_fldate_default()
need to be static for using default argument in a function
Definition: Utils.h:60
static int Read_HeaderCSV_static(std::string namestock, ETime tmscl, Utils::firstlast_dates &dates)
Static version of Read_HeaderCSV.
Definition: Stock.cpp:1519
static int UpdateCSV_Inst(std::string namestock, DataStock &inst_value, DataStock &inst_volume, ETime tmscl, bool opt_tmp=false)
Update file with TimeScale INST.
Definition: Stock.cpp:1555
static PyObject * WrapError
general structure for dates in csv files
Definition: Utils.h:54