ROOT_Application  2.0
C++ Core modules and GUIStock
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DataStock.cpp
Go to the documentation of this file.
1 
8 #include "DataStock.h"
9 
10 #include <iomanip>
11 #include <sstream>
12 #include <cassert>
13 #include <cstring>
14 // for limits_numeric
15 #include <limits>
16 
21 namespace FDS {
23 
24  const int WCOL = 10;
26  const int PRECISION = 2;
27 }
28 
30 
39 size_t reconstruct_stream_operator( std::iostream &is, char * buf_to_ret )
40 {
41 #ifdef DEBUG_DATASTOCK
42  std::cout << "Entry reconstruct_stream_operator " << std::endl;
43 #endif
44  // intermediate, contains the rest of the line
45  char buf_rest[BDS::BUFFER_STREAM];
46  memset ( buf_rest, 0, BDS::BUFFER_STREAM );
47  // contains the date
48  char buf_date[BDS::BUFFER_DATE];
49  memset ( buf_date, 0, BDS::BUFFER_DATE );
50  // correct initialization of the C-array in entry
51  memset ( buf_to_ret, 0, BDS::BUFFER_STREAM );
52 
53  // stop at the end of the stream the first time, or to '!' in a next run
54  is.getline( buf_rest, BDS::BUFFER_STREAM, '!' );
55  //std::cout << "buf_rest:" << buf_rest << std::endl;
56 
57  // check size will be correct, add 3 for terminal characters
58  assert( ( strlen(buf_rest) + BDS::BUFFER_DATE + 3 ) < BDS::BUFFER_STREAM );
59 
60  // read the date again
61  is.seekg(0);
62  is.getline(buf_date, BDS::BUFFER_DATE,',');
63  //std::cout << "buf_date " << buf_date << std::endl;
64 
65  // creates full output: "date , rest ,!", ok works
66  strcat( buf_to_ret, buf_date );
67  strcat( buf_to_ret, ",");
68  strcat( buf_to_ret, buf_rest);
69  // null character added by strcat
70  strcat(buf_to_ret, ",!");
71 
72  size_t len = strlen(buf_to_ret);
73  //unsigned int len = strlen(buf_ret);
74 #ifdef DEBUG_DATASTOCK
75  std::cout << "buf_ret: " << buf_to_ret << std::endl;
76  std::cout << "return buf_ret length " << len << std::endl;
77 #endif
78  // return the len, used to copy the data into stream
79  return len;
80 }
81 
83 // default constructor
84 DataStock::DataStock():date( (time_t) 0) {
85 #ifdef DEBUG_DATASTOCK
86  std::cout << "DataStock default constructor" << std::endl;
87 #endif
88 }
89 
90 DataStock::DataStock(time_t d):date(d) {
91 #ifdef DEBUG_DATASTOCK
92  std::cout << "DataStock constructor with date" << std::endl;
93 #endif
94 }
95 
96 // copy constructor of the base class
97 // bug here ?? seems not here. where is the problem ???
98 DataStock::DataStock (const DataStock & rhs) : date( rhs.date )
99 //DataStock::DataStock (const DataStock & rhs)
100 {
101 #ifdef DEBUG_DATASTOCK
102  std::cout << "Copy Constructor Base date: " << rhs.date << std::endl;
103 #endif
104  //date = rhs.date;
105 }
106 
108 {
109 #ifdef DEBUG_DATASTOCK
110  std::cout << "Move Copy Constructor Base date: " << rhs.date << std::endl;
111 #endif
112  date = rhs.date;
113  // reset
114  rhs.date = 0;
115 }
116 
117 // assignment operator
119 {
120 #ifdef DEBUG_DATASTOCK
121  std::cout << "DataStock Base Normal assignment " << std::endl;
122 #endif
123  if ( this == &rhs ) {
124  return *this;
125  }
126  // copy member, no memory to free/allocate
127  date = rhs.date;
128  return *this;
129 }
130 
131 // move assignment operator
133 {
134 #ifdef DEBUG_DATASTOCK
135  std::cout << "DataStock Base Move assignment " << std::endl;
136 #endif
137  if ( this == &rhs ) {
138  return *this;
139  }
140  // copy
141  date = rhs.date;
142  // reset
143  rhs.date = 0;
144  return *this;
145 }
146 
147 // in utils ?? better ?? yes more option ?
148 // tmp_tm necessary, could be hidden
149 // should be static as well,
150 // used tm because it provides info about the week, necessary for transform
151 struct tm DataStock::GetDateTm() const {
152 
153  //struct tm* localtime(const time_t* timer)
154  struct tm *tmp_tm=localtime(&date);
155  return *tmp_tm;
156 
157  // implementation in DataCSV->ExtractCSV
158  //time_t tmp_date;
159  // seem important to declare the tabular, and send a pointeur to strptime
160  //struct tm tmp_tm = {0, 0, 0, 0, 0, 0, 0, 0, -1, 0, nullptr};
161 }
162 
163 // redirect to Utils
164 std::string DataStock::GetDateString( const bool bhours ) const
165 {
166  // Use Utils::functions, true will include the hour
167  std::string date_string = Utils::Time_tToString( date, bhours );
168  return date_string;
169 }
170 
171 // possible to have a parameter for b_hour
172 // use string, not C array in this case
173 void DataStock::helper_operator_write_base(std::ostream& os) const
174 {
175 #ifdef DEBUG_DATASTOCK
176  std::cout << "DataStock::helper_operator_write_base" << std::endl;
177 #endif
178  // full date 19 characters
179  // always 19 characters for the line, or need parameter in object to decide
180  os << GetDateString();
181 }
182 
183 // must extract date from istream, always first 19 characters, and pass the comma
184 // do not care about the number of charaters if used string
185 // unit test with str_in = "2013-01-01 01:01:01 100.00, 200,300,400"; passes before, now check for comma
187 {
188 #ifdef DEBUG_DATASTOCK
189  std::cout << "DataStock::helper_operator_read_base" << std::endl;
190 #endif
191 
192  // more basic, gains a bit in time
193  char date_buf[BDS::BUFFER_DATE];
194  // istream.get() method does not consume the comma, string method does
195  ios.get( date_buf, BDS::BUFFER_DATE, ',');
196  // here got 44 the comma, need to pass by a get
197  //std::cout << "ios.peek() " << ios.peek() << std::endl;
198 
199  // see unit_test other_data_error, ok now test do not pass
200  if ( ios.peek() != 44 )
201  return 1;
202  ios.get();
203  // extract time_t
204  time_t time = Utils::StringToTime_t( date_buf );
205 
206  // or can use string to extract the date
207  /*
208  std::string str_date;
209  // position is increased
210  std::getline( ios, str_date, ',' );
211  //std::cout << "str_date " << str_date << std::endl;
212  time_t time = Utils::StringToTime_t( str_date );
213  */
214 
215  // can check for error now
216  if ( time == Utils::ERROR_StrToTime )
217  return 1;
218  // parsing date ok
219  SetDate ( time );
220  // correct processing
221  return 0;
222 }
223 
226 #ifdef DEBUG_DATASTOCK
227  std::cout <<"Constructor default SimpleData" << std::endl;
228 #endif
229 }
230 
232 #ifdef DEBUG_DATASTOCK
233  std::cout <<"Constructor SimpleData with value" << std::endl;
234 #endif
235 }
236 
237 SimpleData::SimpleData(time_t d,type_value_data ivalue):DataStock(d),value(ivalue) {
238 #ifdef DEBUG_DATASTOCK
239  std::cout <<"Constructor SimpleData default date and value" << std::endl;
240 #endif
241 }
242 
243 SimpleData::SimpleData( unsigned int /*nb*/ ) : DataStock(),value(0.) {}
244 
245 //copy constructor
246 // see comment DataCSV, do not use list init.
248 //,value(rhs.value)
249 {
250 #ifdef DEBUG_DATASTOCK
251  std::cout <<"Copy Constructor SimpleData" << std::endl;
252 #endif
253  value = rhs.value;
254 }
255 
256 // Move copy constructor, certainly need same in base
257 // do not call the correct move copy
258 // rvalue considered as lvalue inside the function
259 SimpleData::SimpleData( SimpleData && rhs ) : DataStock( std::move(rhs) )
260 {
261 #ifdef DEBUG_DATASTOCK
262  std::cout <<"Move Copy Constructor SimpleData" << std::endl;
263 #endif
264  // copy data
265  value = rhs.value;
266  // reset origin
267  rhs.value = 0;
268 }
269 
270 // normal assignment
272 {
273 #ifdef DEBUG_DATASTOCK
274  std::cout << "SimpleData Normal assignment " << std::endl;
275 #endif
276  // Check self-assignment
277  if ( this == &rhs ) {
278  return *this;
279  }
280  // call base class
281  DataStock::operator=( rhs );
282  // no memory to delete, copy data, no memory to allocate
283  value = rhs.value;
284  return *this;
285 }
286 
287 // move assignment
289 {
290 #ifdef DEBUG_DATASTOCK
291  std::cout << "SimpleData Move assignment " << std::endl;
292 #endif
293  // Check self-assignment
294  if ( this == &rhs ) {
295  return *this;
296  }
297  // call base class, do not call the correct one
298  DataStock::operator=( std::move(rhs) );
299  // copy data
300  value = rhs.value;
301  // reset
302  rhs.value = 0;
303  return *this;
304 }
305 
306 std::vector<type_value_data> SimpleData::GetValues() const
307 {
308  std::vector<type_value_data> vec_value;
309  vec_value.push_back( value );
310  return vec_value;
311 }
312 
313 void SimpleData::SetValues( std::vector<type_value_data> & vec)
314 {
315  assert( vec.size() == 1 );
316  value = vec[0];
317 }
318 
319 // use when reading dscv file
320 void SimpleData::ExtractCSVLine(std::vector<std::string> & linecsv) {
321  // set date and value
322  SetDate( Utils::StringToTime_t( linecsv[0] ) );
323  SetValue( Utils::fromString<type_value_data>(linecsv[1]) );
324 }
325 
326 // use GetValue() if not virtual, need to cast
327 bool SimpleData::HasChanged(const DataStock & data_to_check ) const
328 {
329 #ifdef DEBUG_CPP
330  std::cout << "Entry SimpleData::HasChanged" << std::endl;
331  //std::cout << "GetDate() " << GetDate() << std::endl;
332  std::cout << "Date of the old data " << GetDate() << std::endl;
333  std::cout << "Date of the old data " << GetDateString() << std::endl;
334  std::cout << " value old " << GetValue() << std::endl;
335  //std::cout << "data_to_check " << data_to_check << std::endl;
336  std::cout << "Date of the new data " << data_to_check.GetDate() << std::endl;
337  std::cout << "Date of the new data " << data_to_check.GetDateString() << std::endl;
338  //std::cout << "new value " << ((SimpleData &)data_to_check).GetValue() << std::endl;
339  std::cout << "new value " << static_cast<const SimpleData &>(data_to_check).GetValue() << std::endl;
340 #endif
341 
342  //if same date means that it is an update
343  /*
344  if ( GetDate() != data_to_check.GetDate() ) {
345 #ifdef DEBUG_CPP
346  std::cout << " SimpleData dates differ, return true " << std::endl;
347 #endif
348  return true;
349 
350  // same date, check if the value changed
351  } */
352  //if ( GetValue() != ((SimpleData &)data_to_check).GetValue() ) {
353  if ( GetValue() != static_cast<const SimpleData &>(data_to_check).GetValue() ) {
354 #ifdef DEBUG_CPP
355  std::cout << " SimpleData value differ, return true " << std::endl;
356 #endif
357  return true;
358  } //else
359  return false;
360 }
361 
362 // may improve if volume
363 void SimpleData::PrintData( const unsigned int verbose ) const
364 {
365  // intermediate, sure tellp is correct and set to 0
366  std::ostringstream tmp_os;
367 
368  if ( verbose == 1 ) {
369  std::cout << "PrintData SimpleData " << std::endl;
370  std::cout << std::setw(25) <<"date" << std::setw(FDS::WCOL+1) << "value" << std::endl;
371  }
372  // use friend operator << with SimpleData
373  tmp_os << *this;
374 
375  // format of output with header
376  if ( verbose == 1 )
377  std::cout << " " << tmp_os.str() << std::endl;
378  else
379  std::cout << tmp_os.str() << std::endl;
380 
381  return;
382 }
383 
384 void SimpleData::helper_operator_write(std::ostream &os) const
385 {
386  os << "," << std::setprecision(FDS::PRECISION) << std::setw(FDS::WCOL) << std::fixed << GetValue();
387 }
388 
389 void SimpleData::helper_operator_read(std::iostream &ios)
390 {
391  // set value from the stream, got form the string up to end or first delimiter character
392  SetValue( Utils::fromStreamToDouble( ios, ',') );
393 }
394 
396 
397 // to have same behaviour than other classes, fill the vector with default values
398 MultiData::MultiData() : DataStock(), nb_data(1) {
399 #ifdef DEBUG_DATASTOCK
400  std::cout <<"Constructor default MultiData" << std::endl;
401 #endif
402 
403  //nb_data = 1;
404  // set values with a default 0.
405  values.push_back( 0. );
406  //values = {0.};
407  //values = std::vector<type_value_data>( 1, 0.); //{0.};
408  //std::cout << "sizeof values " << sizeof(values) << std::endl;
409 
410 }
411 
412 MultiData::MultiData( unsigned int nbdata ) : DataStock(), nb_data(nbdata) {
413 #ifdef DEBUG_DATASTOCK
414  std::cout <<"Constructor MultiData with size: " << nbdata << std::endl;
415 #endif
416  // set values with a default 0.
417  //values.push_back( 0. );
418  //nb_data = nbdata;
419  values = std::vector<type_value_data>( nb_data, 0. );
420  //std::cout << "sizeof values " << sizeof(values) << std::endl;
421 }
422 
423 MultiData::MultiData(time_t d, std::vector<type_value_data> ivalues) :
424  DataStock(d), nb_data(ivalues.size()), values(ivalues) {
425 #ifdef DEBUG_DATASTOCK
426  std::cout <<"Constructor MultiData date and values " << std::endl;
427 #endif
428 }
429 
430 // copy constructor, works here with initilizers ??
431 // here necessary in list, because const ! certainly a strange bug with DataCSV...
432 MultiData::MultiData( const MultiData & rhs ) : DataStock(rhs), nb_data(rhs.nb_data)
433 // values(rhs.values)
434 {
435 #ifdef DEBUG_DATASTOCK
436  std::cout <<"Copy Constructor MultiData" << std::endl;
437 #endif
438  // check const nb_data
439  assert ( nb_data == rhs.nb_data );
440  assert ( nb_data == rhs.values.size() );
441  values = rhs.values;
442 }
443 
444 // move copy constructor
445 MultiData::MultiData( MultiData && rhs ) : DataStock( std::move(rhs) ), nb_data(rhs.nb_data)
446 {
447 #ifdef DEBUG_DATASTOCK
448  std::cout <<"Move Copy Constructor MultiData" << std::endl;
449 #endif
450  // copy data, cannot optimize here
451  //nb_data = rhs.nb_data;
452  values = rhs.values;
453  // no pointer to modify
454  // reset origin
455  //rhs.value = 0;
456  // clear vector ? NO ! default size is one, set to zero maybe
457 }
458 
459 
460 // normal assignment
462 {
463 #ifdef DEBUG_DATASTOCK
464  std::cout << "MultiData Normal assignement " << std::endl;
465 #endif
466  // Check self-assignment
467  if ( this == &rhs ) {
468  return *this;
469  }
470  // should not happen !
471  assert( nb_data == rhs.nb_data );
472  assert ( values.size() == rhs.values.size() );
473 
474  // call base class
475  DataStock::operator=( rhs );
476  // copy data, no memory to allocate
477  // cannot here because const
478  //nb_data = rhs.nb_data;
479  values = rhs.values;
480 
481  return *this;
482 }
483 
485 {
486 #ifdef DEBUG_DATASTOCK
487  std::cout << "MultiData Move assignment " << std::endl;
488 #endif
489  // Check self-assignment
490  if ( this == &rhs ) {
491  return *this;
492  }
493  // call base class, do not call the correct one
494  DataStock::operator=( std::move(rhs) );
495  // copy data
496  //nb_data = rhs.nb_data;
497  values = rhs.values;
498  // reset, maybe set to zero
499  return *this;
500 }
501 
502 // to use stl max algoithm
503 // limits_
505 {
506  type_value_data max = -99999;
507  std::vector<type_value_data>::const_iterator it;
508 
509  for ( it = values.begin(); it != values.end(); ++it ) {
510  if ( (*it) > max ) max = (*it);
511  }
512  return max;
513 }
514 
515 // to use stl min algorithm
517 {
518  type_value_data min = 99999;
519  std::vector<type_value_data>::const_iterator it;
520  for ( it = values.begin(); it != values.end(); ++it ) {
521  if ( (*it) < min ) min = (*it);
522  }
523  return min;
524 }
525 
526 // other class fill a vector with their current values
527 // just need to return a copy, ref possible, more efficient, but not for others classes
528 // should not matter the return type ?? to test
529 std::vector<type_value_data> MultiData::GetValues() const
530 {
531  return values;
532 }
533 
534 void MultiData::SetValues( std::vector<type_value_data> & vec)
535 {
536  //assert size (nb_data), constant during its life time not a bad idea
537  assert ( nb_data == vec.size() );
538  assert ( vec.size() == values.size() );
539  values = vec;
540 }
541 
542 // Check vector of values only
543 // GetValues is virtual, no need of explicit cast !
544 bool MultiData::HasChanged( const DataStock & data_to_check ) const
545 {
546  // here can test entry has the correct type
547  assert ( nb_data == dynamic_cast<const MultiData &>(data_to_check).nb_data );
548  // test also than correct virtual function of MultiData is called
549  assert ( nb_data == data_to_check.GetValues().size() );
550 
551  // compare the vector directly, return by copy here ?
552  if ( GetValues() != data_to_check.GetValues() ) {
553 #ifdef DEBUG_CPP
554  std::cout << " MultiData at least one value differ, return true " << std::endl;
555 #endif
556  return true;
557  }
558  return false;
559 }
560 
561 // certainly much better algo to use
562 void MultiData::ExtractCSVLine(std::vector<std::string> & linecsv)
563 {
564  assert( (nb_data + 1) == linecsv.size() );
565  time_t tmp_date;
566  // could fix the size here
567  std::vector<type_value_data> tmp_values;
568 
569  // use Utils
570  tmp_date = Utils::StringToTime_t( linecsv[0] );
571 
572  // copy, swap better
573  for ( auto v= linecsv.begin()+1; v != linecsv.end(); ++v ) {
574  tmp_values.push_back( Utils::fromString<type_value_data>(*v) );
575  }
576 
577  SetData(tmp_date,tmp_values);
578 }
579 
580 // problem when runing prog > out, tellp is increased in this case, works with output !! ??
581 // std::cout bound to an other ostream maybe ??
582 void MultiData::PrintData( const unsigned int verbose ) const
583 {
584  // intermediate, sure tellp is correct and set to 0
585  std::ostringstream tmp_os;
586 
587  if ( verbose == 1 ) {
588  std::cout << "PrintData MultiData " << std::endl;
589  std::cout << std::setw(25) <<"date" << std::setw(FDS::WCOL+1) << "values" << std::endl;
590  }
591  // use operator << with MultiCSV
592  tmp_os << *this;
593  // can test here
594 
595  // format of output with header
596  if ( verbose == 1 )
597  std::cout << " " << tmp_os.str() << std::endl;
598  else
599  std::cout << tmp_os.str() << std::endl;
600  return;
601 
602 }
603 
604 void MultiData::helper_operator_write(std::ostream &os) const
605 {
606  for ( unsigned int i=0; i< nb_data; ++i) {
607  os << "," << std::setprecision(FDS::PRECISION) << std::setw(FDS::WCOL) << std::fixed << values[i];
608  }
609 }
610 
611 void MultiData::helper_operator_read(std::iostream &ios)
612 {
613  std::vector<type_value_data> vec_values;
614  //vec_values.reserve(4);
615 
616  // loop until "," or end line, always 4 here
617  for ( unsigned int i=0; i< nb_data; ++i) {
618  // only stream and char[] are used inside
619  vec_values.push_back( Utils::fromStreamToDouble( ios, ',') );
620  }
621  SetValues(vec_values);
622 }
623 
625 
626 DataCSV::DataCSV(): DataStock(), open(0.),high(0.),low(0.),close(0.)
627 {
628 #ifdef DEBUG_DATASTOCK
629  std::cout << "Constructor default DataCSV" << std::endl;
630 #endif
631 }
632 
634  type_value_data ilow, type_value_data iclose) :
635  DataStock(d), open(iopen),high(ihigh),low(ilow),close(iclose) {
636 #ifdef DEBUG_DATASTOCK
637  std::cout << "Constructor DataCSV with 5 arguements " << std::endl;
638 #endif
639 }
640 
641 DataCSV::DataCSV( unsigned int /*nb*/ ): DataStock(), open(0.),high(0.),low(0.),close(0.) {}
642 
643 // copy constructor, must call base copy constructor
644 // IMPORTANT, Do not work with list initialization !! ??
646 {
647 #ifdef DEBUG_DATASTOCK
648  std::cout << "copy constructor DataCSV " << std::endl;
649 #endif
650  // copy private member of this class
651  open = rhs.open;
652  high = rhs.high;
653  low = rhs.low;
654  close = rhs.close;
655 }
656 
657 // move copy constructor
658 DataCSV::DataCSV( DataCSV && rhs ) : DataStock( std::move(rhs) )
659 {
660 #ifdef DEBUG_DATASTOCK
661  std::cout <<"Move Copy Constructor DataCSV" << std::endl;
662 #endif
663  // copy data, cannot optimize here
664  open = rhs.open;
665  high = rhs.high;
666  low = rhs.low;
667  close = rhs.close;
668  // no pointer to modify
669  // reset origin
670  rhs.open = 0.;
671  rhs.high = 0.;
672  rhs.low = 0.;
673  rhs.close = 0.;
674 }
675 
676 // normal assignment
678 {
679 #ifdef DEBUG_DATASTOCK
680  std::cout << "DataCSV Normal assignement " << std::endl;
681 #endif
682  // Check self-assignment
683  if ( this == &rhs ) {
684  return *this;
685  }
686  // call base class operator=
687  DataStock::operator=( rhs );
688  // copy data, no memory to free/allocate in this case
689  open = rhs.open;
690  high = rhs.high;
691  low = rhs.low;
692  close = rhs.close;
693  return *this;
694 }
695 
696 // move assignment
698 {
699 #ifdef DEBUG_DATASTOCK
700  std::cout << "DataCSV Move assignment " << std::endl;
701 #endif
702  // Check self-assignment
703  if ( this == &rhs ) {
704  return *this;
705  }
706  // call base class, do not call the correct one
707  DataStock::operator=( std::move(rhs) );
708  // copy data
709  open = rhs.open;
710  high = rhs.high;
711  low = rhs.low;
712  close = rhs.close;
713  // reset
714  rhs.open = 0.;
715  rhs.high = 0.;
716  rhs.low = 0.;
717  rhs.close = 0.;
718  return *this;
719 }
720 
721 // reset to initial min and max values in particular
722 // could use maxint minint c++11
723 // http://en.cppreference.com/w/cpp/types/numeric_limits/max
725 {
726  //low = 100000;
727  //high = -100000;
728  low = std::numeric_limits<type_value_data>::max();
729  high = std::numeric_limits<type_value_data>::min();
730  //open=0;
731  //close=0;
732 }
733 
734 //void DataCSV::SetData(type_value_data o,type_value_data h,type_value_data l,type_value_data c)
735 void DataCSV::SetValues(const type_value_data iopen, const type_value_data ihigh,
736  const type_value_data ilow, const type_value_data iclose)
737 {
738  open = iopen;
739  high = ihigh;
740  low = ilow;
741  close = iclose;
742 }
743 
744 void DataCSV::SetData(const time_t d, const type_value_data o,const type_value_data h,
745  const type_value_data l,const type_value_data c)
746 {
747  date= d;
748  open = o;
749  high = h;
750  low = l;
751  close = c;
752 }
753 
754 void DataCSV::SetData( const time_t d, const std::vector<type_value_data> & vec )
755 {
756  date= d;
757  open = vec[0];
758  high = vec[1];
759  low = vec[2];
760  close = vec[3];
761 }
762 
763 void DataCSV::SetValues( std::vector<type_value_data> & vec )
764 {
765  open = vec[0];
766  high = vec[1];
767  low = vec[2];
768  close = vec[3];
769 }
770 
771 std::vector<type_value_data> DataCSV::GetValues() const
772 {
773  std::vector<type_value_data> vec_value;
774  vec_value.push_back( open );
775  vec_value.push_back( high );
776  vec_value.push_back( low );
777  vec_value.push_back( close );
778  return vec_value;
779 }
780 
781 // to delete anyway
782 void DataCSV::ExtractCSVLine(std::vector<std::string> & linecsv)
783 {
784 #ifdef DEBUG_CPP
785  std::cout << "Extractline DataCSV" << std::endl;
786 #endif
787 
788  // at least 5, maybe volume included in file
789  //assert( linecsv.size() >= 5 );
790 
791  time_t tmp_date;
792  type_value_data tmp_open,tmp_high,tmp_low,tmp_close;
793 
794  tmp_date = Utils::StringToTime_t( linecsv[0] );
795  tmp_open = Utils::fromString<type_value_data> ( linecsv[1] );
796  tmp_high = Utils::fromString<type_value_data> ( linecsv[2] );
797  tmp_low = Utils::fromString<type_value_data> ( linecsv[3] );
798  tmp_close = Utils::fromString<type_value_data>( linecsv[4] );
799 
800  SetData( tmp_date, tmp_open, tmp_high, tmp_low, tmp_close);
801 }
802 
803 // call by ListDataStock::AddToList,
804 // called by Stock::AddListDataToStock, compare if data_to_check is a more recent version than prev_data
805 // case of a candle if not finished
806 // test the time, to be sure to compare the same candle
807 // use DataStock entry, if want to used as pure virtual
808 // with change of ChronologicAt, which returns the correct type could use explicit DataCSV type..to see later
809 bool DataCSV::HasChanged( const DataStock & data_to_check ) const
810 {
811 #ifdef DEBUG_CPP
812  std::cout << "\n\t Entry DataCSV::HasChanged " << std::endl;
813  //std::cout << "Date of the old data " << GetDate() << std::endl;
814  std::cout << "Date of the old data " << GetDateString() << std::endl;
815  std::cout << "old Close " << GetClose() << std::endl;
816  //std::cout << "data_to_check " << data_to_check << std::endl;
817  //std::cout << "Date of the new data " << data_to_check.GetDate() << std::endl;
818  std::cout << "Date of the new data " << data_to_check.GetDateString() << std::endl;
819  std::cout << "new Close " << ((DataCSV &)data_to_check).GetClose() << std::endl;
820 #endif
821 
822  // if same date means that it is an update,
823  // already some tests in case of InsertBegin, different tests but similar... never different ??
824  // test here or before ? better to have same behaviour/logic for all the DataStock
825  if ( GetDate() != data_to_check.GetDate() ) {
826  std::cout << " date differ so it is a new data, return replace_last false" << std::endl;
827  return false;
828  // real test, date should be always identical here ??
829  } else {
830  std::cout << "Same date, check Close " << std::endl;
831  // could use dynamic or static cast, maybe use real type in parameter now ?
832  if ( GetClose() != ((DataCSV &)data_to_check).GetClose() ) {
833  //if ( GetClose() != (data_to_check).GetClose() ) {
834  std::cout << " Close differ, real update of the candle, return true " << std::endl;
835  return true;
836  } else {
837  std::cout << " Close identical, mean that is the beginning of a new value, return false " << std::endl;
838  return false;
839  }
840  }
841 }
842 
843 void DataCSV::AdditionData(const DataCSV & new_data)
844 {
845  if (new_data.high > high )
846  high = new_data.high;
847  if (new_data.low < low )
848  low = new_data.low;
849 }
850 
851 // could assign close by default ? see with algo
852 // no, will make dependent of the order
853 void DataCSV::AdditionData( const SimpleData & new_data)
854 {
855  if ( new_data.GetValue() > high )
856  high = new_data.GetValue();
857  if ( new_data.GetValue() < low )
858  low = new_data.GetValue();
859 }
860 
861 void DataCSV::PrintData( const unsigned int verbose ) const
862 {
863  // intermediate, sure tellp is correct and set to 0
864  std::ostringstream tmp_os;
865 
866  if ( verbose == 1 ) {
867  std::cout << "PrintData DataCSV"<< std::endl;
868  std::cout << std::setw(25) <<"date" << std::setw(FDS::WCOL+1) << "open" <<
869  std::setw(FDS::WCOL+1) << "high" << std::setw(FDS::WCOL+1) << "low" <<
870  std::setw(FDS::WCOL+1) << "close " << std::endl;
871  }
872  // use operator << with DataCSV
873  tmp_os << *this;
874 
875  //std::cout << tmp_os.str() << std::endl;
876  // format of output with header
877  if ( verbose == 1 )
878  std::cout << " " << tmp_os.str() << std::endl;
879  else
880  std::cout << tmp_os.str() << std::endl;
881 
882  return;
883 }
884 
885 void DataCSV::helper_operator_write(std::ostream &os) const
886 {
887  // format for DataCSV
888  os << "," << std::setprecision(FDS::PRECISION) << std::setw(FDS::WCOL) << std::fixed
889  << GetOpen() << "," << std::setw(FDS::WCOL) << GetHigh() << ","
890  << std::setw(FDS::WCOL) << GetLow() << "," << std::setw(FDS::WCOL) << GetClose();
891  //return os;
892 }
893 
894 void DataCSV::helper_operator_read(std::iostream &ios)
895 {
896  std::vector<type_value_data> vec_values;
897  vec_values.reserve(4);
898 
899  // loop until "," or end line, always 4 here
900  for ( unsigned int i=0; i< 4; ++i) {
901  // only stream and char[] are used inside
902  vec_values.push_back( Utils::fromStreamToDouble( ios, ',') );
903  }
904  SetValues(vec_values);
905 }
906 
909 
910 bool operator==( const SimpleData & lhs, const SimpleData & rhs ) {
911 
912  return ( ( lhs.date == rhs.date ) &&
913  ( lhs.value == rhs.value ) );
914 }
915 
916 bool operator==( const MultiData & lhs, const MultiData & rhs ) {
917 
918  return ( ( lhs.date == rhs.date ) &&
919  ( lhs.values == rhs.values ) );
920 }
921 
922 bool operator==( const DataCSV & lhs, const DataCSV & rhs ) {
923 
924  return ( ( lhs.date == rhs.date ) &&
925  ( lhs.open == rhs.open ) &&
926  ( lhs.high == rhs.high ) &&
927  ( lhs.low == rhs.low ) &&
928  ( lhs.close == rhs.close ) );
929 }
930 
932 
933 
934 
935 // define only for DataStock base and use polymorphisme on obj
936 std::ostream& operator<<(std::ostream& os, const DataStock& obj)
937 {
938  // call base for the date only if pos == 0
939  if ( os.tellp() == 0 || os.tellp() == -1 )
940  obj.helper_operator_write_base( os );
941 
942  // call a virtual function
943  obj.helper_operator_write( os );
944 
945  return os;
946 }
947 
948 std::iostream& operator>>(std::iostream& ios, DataStock& obj)
949 {
950  // C buffer to renconstruct the stream, correctly initialized with memset in function
951  char buf_ret[BDS::BUFFER_STREAM];
952  size_t len_buf;
953 
954  // here it is an error, because it means than an object has no data to read, set fail()
955  if ( ( (ios.rdstate() & std::iostream::eofbit ) != 0 ) ||
956  ( (ios.rdstate() & std::iostream::failbit) != 0 ) ) {
957  std::cout << "DataStock eofbit or fail nothing more to read from the stream, set fail " << std::endl;
958  ios.setstate ( std::iostream::failbit);
959  return ios;
960  }
961 
962  // call base to read the date, bytes are consumed, stream position advanced
963  if ( obj.helper_operator_read_base( ios ) != 0 ) {
964  //std::cout << "Error in parsing date, set fail " << std::endl;
965  ios.setstate ( std::iostream::failbit);
966  return ios;
967  }
968 
969  // specific to each object
970  obj.helper_operator_read( ios );
971 
972  //for all
973  // if it is the first call, eof will return true
974  // if it is an other will peek '!' and discard unused bytes
975  // set eofbit to be sure a potential caller will return directly ( and generate a fail in this case )
976  if ( ios.eof() || (ios.peek() == '!') ) {
977  ios.setstate ( std::iostream::eofbit);
978  return ios;
979  }
980  // is should point to the resting values before the call
981  // if more data, need to reconstruct the stream
982  len_buf = reconstruct_stream_operator( ios, buf_ret );
983 
984  // write the total array into the stream and pass to the next object
985  ios.seekg(0);
986  ios.write( buf_ret, len_buf );
987  return ios;
988 }
989 
990 std::string& operator<<(std::string &line_csv, const DataStock& obj)
991 {
992  std::ostringstream stream;
993  // ok, now stream.tellp is increased if line is non empty
994  stream << line_csv << obj;
995  line_csv = stream.str();
996  return line_csv;
997 }
998 
999 std::string& operator>>(std::string &line_csv, DataStock& obj)
1000 {
1001  std::stringstream ss(line_csv);
1002  ss >> obj;
1003 
1004  // everything done correctly, clear the string
1005  if ( ss.eof() == true && ss.fail() == false )
1006  line_csv.clear();
1007  // error, insure string is not empty
1008  else
1009  line_csv = ss.str();
1010 
1011  return line_csv;
1012 }
1013 
1014 
Generalisation of SimpleData, contains a vector of type_value_data values.
Definition: DataStock.h:432
std::iostream & operator>>(std::iostream &ios, DataStock &obj)
Definition: DataStock.cpp:948
SimpleData()
Default constructor, set value to 0.
Definition: DataStock.cpp:225
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
void helper_operator_write_base(std::ostream &os) const
Helper function for operator>> for writing date to output.
Definition: DataStock.cpp:173
std::ostream & operator<<(std::ostream &os, const DataStock &obj)
Definition: DataStock.cpp:936
type_value_data high
Definition: DataStock.h:507
virtual void ExtractCSVLine(std::vector< std::string > &linecsv)
Extract date and data from a split string.
Definition: DataStock.cpp:562
type_value_data GetValue() const
Get the unique value.
Definition: DataStock.h:391
type_value_data GetClose() const
Definition: DataStock.h:555
DataStock()
Default constructor set date to 0.
Definition: DataStock.cpp:84
void SetDate(const time_t d)
Modify the date.
Definition: DataStock.h:130
const int BUFFER_DATE
Contains the date, exactly 19 characters + terminal (terminal not really crucial) ...
Definition: DataStock.h:79
double fromStreamToDouble(std::iostream &stream, char delim)
Read the next character of a stream as a double.
Definition: Utils.cpp:45
virtual void ExtractCSVLine(std::vector< std::string > &linecsv)
Extract date and data from a split string.
Definition: DataStock.cpp:782
const unsigned int nb_data
Number of data stored in the vector.
Definition: DataStock.h:437
const int BUFFER_STREAM
Maximum size buffer intermediate for stream.
Definition: DataStock.h:77
virtual bool HasChanged(const DataStock &data_to_check) const
Check if data are different.
Definition: DataStock.cpp:544
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:467
double type_value_data
Type of the floating values to be stored, can be set to float or double before compilation.
Definition: DataStock.h:49
DataCSV()
Default constructor, set date and all values to 0.
Definition: DataStock.cpp:626
void SetValue(const type_value_data ivalue)
Set the unique value.
Definition: DataStock.h:393
void PrintData(const unsigned int verbose=0) const
User friendly output on screen.
Definition: DataStock.cpp:861
void PrintData(const unsigned int verbose=0) const
User friendly output on screen.
Definition: DataStock.cpp:363
void SetValues(std::vector< type_value_data > &vec)
Set only values, do not modify the date.
Definition: DataStock.cpp:534
virtual void helper_operator_read(std::iostream &ios)
Definition: DataStock.cpp:389
return values
Definition: ObjectStock.cxx:37
void PrintData(const unsigned int verbose=0) const
User friendly output on screen.
Definition: DataStock.cpp:582
DataStock & operator=(const DataStock &rhs)
Normal assignment.
Definition: DataStock.cpp:118
DataCSV & operator=(const DataCSV &rhs)
Normal assignment.
Definition: DataStock.cpp:677
void Reset()
Set high and low values respectively to the minimum and maximum possible values for the type...
Definition: DataStock.cpp:724
type_value_data close
Definition: DataStock.h:507
virtual void helper_operator_write(std::ostream &os) const
Definition: DataStock.cpp:384
Data type to describe Japanese candlesticks : open, high, low and close values.
Definition: DataStock.h:502
Classes for data to be stored in ListDataStock.
type_value_data low
Definition: DataStock.h:507
const time_t ERROR_StrToTime
Error code returned by StringToTime_t if the string cannot be parsed correctly Must be a time_t...
Definition: Utils.h:51
virtual std::vector< type_value_data > GetValues() const
Return the values in a vector, always 4 values: open, high, low, close.
Definition: DataStock.cpp:771
virtual void helper_operator_write(std::ostream &os) const
Definition: DataStock.cpp:604
virtual std::vector< type_value_data > GetValues() const
Return the value(s) in a vector.
Definition: DataStock.cpp:306
virtual std::vector< type_value_data > GetValues() const =0
Return the value(s) in a vector.
virtual void AdditionData(const DataCSV &new_data)
With an other candlestick.
Definition: DataStock.cpp:843
int helper_operator_read_base(std::iostream &ios)
Helper function for operator<< for reading date from input streams.
Definition: DataStock.cpp:186
bool operator==(const SimpleData &lhs, const SimpleData &rhs)
Definition: DataStock.cpp:910
std::string Time_tToString(const time_t &time, const bool b_hour)
Return a string representing the date All times are expressed in the localtime.
Definition: Utils.cpp:157
virtual void SetValues(std::vector< type_value_data > &vec)
Set the values with the same order.
Definition: DataStock.cpp:763
std::vector< type_value_data > values
Vector for storing values.
Definition: DataStock.h:440
virtual void helper_operator_read(std::iostream &ios)
Definition: DataStock.cpp:611
virtual void helper_operator_read(std::iostream &ios)=0
time_t StringToTime_t(const std::string &str_date)
Return the time_t from a string .
Definition: Utils.cpp:93
virtual void helper_operator_write(std::ostream &os) const =0
virtual std::vector< type_value_data > GetValues() const
Return the value(s) in a vector.
Definition: DataStock.cpp:529
type_value_data GetOpen() const
Definition: DataStock.h:552
const int WCOL
Witdh of the values with setw.
Definition: DataStock.cpp:24
const int PRECISION
Precison of floating numbers.
Definition: DataStock.cpp:26
Derive class which contains only one value of type type_value_data (float or double).
Definition: DataStock.h:335
virtual bool HasChanged(const DataStock &data_to_check) const
Check if data are different.
Definition: DataStock.cpp:809
virtual void helper_operator_write(std::ostream &os) const
Definition: DataStock.cpp:885
MultiData()
Default constructor, set number of data to 1 and a default value of 0.
Definition: DataStock.cpp:398
virtual bool HasChanged(const DataStock &data_to_check) const
Check if data are different.
Definition: DataStock.cpp:327
SimpleData & operator=(const SimpleData &rhs)
Normal assignment.
Definition: DataStock.cpp:271
type_value_data GetLow() const
Definition: DataStock.h:554
time_t GetDate() const
Get the date data member.
Definition: DataStock.h:126
type_value_data GetHigh() const
Definition: DataStock.h:553
MultiData & operator=(const MultiData &rhs)
Normal assignment.
Definition: DataStock.cpp:461
std::string GetDateString(const bool bhours=true) const
Return the date in a string format: "YEAR-MOnth-DAy HH:MM:SS" (2014-11-10 13::25::00) ...
Definition: DataStock.cpp:164
size_t reconstruct_stream_operator(std::iostream &is, char *buf_to_ret)
Reconstruct a stream in skipping the values already consumed This is used by friend operator>> ( iost...
Definition: DataStock.cpp:39
virtual void helper_operator_read(std::iostream &ios)
Definition: DataStock.cpp:894
virtual void ExtractCSVLine(std::vector< std::string > &linecsv)
Extract the data from a splitted string.
Definition: DataStock.cpp:320
type_value_data open
Definition: DataStock.h:507
time_t date
All data have a date associated.
Definition: DataStock.h:97
virtual type_value_data GetMinimum() const
Get the minimum value.
Definition: DataStock.cpp:516
virtual type_value_data GetMaximum() const
Get the maximum value.
Definition: DataStock.cpp:504
virtual void SetValues(std::vector< type_value_data > &vec)
Set only values, do not modify the date.
Definition: DataStock.cpp:313
type_value_data value
Definition: DataStock.h:338
Abstract base class for all Data to be stored in ListDataStock.
Definition: DataStock.h:90