Trading System API  3.0
Library for Simulating and Deploying Trading and Investment Strategies
TSASupport.h
1 /* ===================================================================
2 *
3 * T R A D I N G S Y S T E M A P I ™
4 * Copyright © 1999 - 2014 by Peter Ritter ( TradingSystemAPI.com )
5 * A L L R I G H T S R E S E R V E D
6 *
7 * Consult your license regarding permissions and restrictions.
8 * You may obtain a copy of the License at:
9 * http://www.TradingSystemAPI.com/licenses/LICENSE-TSAPI-3.0.html
10 *
11 * ====================================================================
12 */
13 
14 #ifndef TSA_SUPPORT__INCLUDED
15 #define TSA_SUPPORT__INCLUDED
16 
17 #include <vector>
18 #include <ostream>
19 #include <mutex>
20 #include <chrono>
21 #include <map>
22 #include <atomic>
23 #include <queue>
24 
25 #include "TSATypeDef.h"
26 #include "TSAString.h"
27 #include "TSAFile.h"
28 #include "TSAError.h"
29 
30 namespace tsa {
31 
32  /*
33  ** ====================================================
34  ** > > > class spin_lock < < <
35  ** ====================================================
36  */
37  class spin_lock
38  {
39  private:
40  std::atomic<bool> m_value;
41  public:
42  spin_lock() : m_value(false) { };
43  void lock(){while (m_value.exchange(true));}
44  void unlock(){m_value.store(false);}
45  bool is_locked(){return m_value.load();}
46  };
47 
48  /*
49  ** ====================================================
50  ** > > > atomic queue < < <
51  ** ====================================================
52  */
53  namespace atomic {
54 
55  template<typename T>
56  class queue : public object {
57  private:
58  mutable std::mutex m_mutex;
59  std::queue<T> m_data_queue;
60  std::condition_variable m_data_cond;
61  public:
62  queue(void) {}
63  void push(T& value) {
64  std::lock_guard<std::mutex> lk(m_mutex);
65  m_data_queue.push(value);
66  m_data_cond.notify_one();
67  }
68 
69  void wait_and_pop(T& value) {
70  std::unique_lock<std::mutex> lk(m_mutex);
71  m_data_cond.wait(lk, [this] {return !m_data_queue.empty(); });
72  value = m_data_queue.front();
73  m_data_queue.pop();
74  }
75 
76  bool wait_until_and_pop(T& value, const std::chrono::microseconds& usec) {
77  std::unique_lock<std::mutex> lk(m_mutex);
78  auto now = std::chrono::system_clock::now();
79  if (m_data_cond.wait_until(lk,
80  now + usec, [this] {return !m_data_queue.empty(); }))
81  {
82  tsa_assert(!m_data_queue.empty());
83  value = m_data_queue.front();
84  m_data_queue.pop();
85  return true;
86  }
87  else { return false; }
88  }
89 
90  bool try_pop(T& value) {
91  std::lock_guard<std::mutex> lk(m_mutex);
92  if (m_data_queue.empty()) {
93  return false;
94  }
95  value = m_data_queue.front();
96  m_data_queue.pop();
97  return true;
98  }
99  };
100  }
101 
102  /*
103  ** ====================================================
104  ** > > > class named_values < < <
105  ** ====================================================
106  */
107 
111  class dll_export named_values : public tsa::object{
112  std::map<std::string, variant> m_map;
113  public:
115  named_values(void);
117  named_values(const named_values& other);
119  named_values(named_values&& other);
121  virtual ~named_values(void);
123  void operator=(const named_values& other);
125  void operator=(named_values&& other);
127  void from_string(const std::string& property_string);
129  void from_file(const os::path&);
131  variant& operator[](const std::string& key);
133  const variant& operator[](const std::string& key)const;
135  void set(const std::string& key, const variant& value);
137  void add(const std::string& key, const variant& value);
139  void add(const std::pair<std::string, variant>& pair);
141  const variant& value(const std::string& key)const;
142 
143  variant& value(const std::string& key);
145  bool exists(const std::string& key)const;
147  void remove(const std::string& key, bool error_on_missing_key = true);
149  size_t size(void)const;
151  void print(std::ostream&)const;
153  void clear(void);
154  public:
155  void print_values(std::ostream& stream)const;
156  };
157 
159  typedef named_values named_args;
160 
161  /*
162  ** ====================================================
163  ** > > > class timer < < <
164  ** ====================================================
165  */
169  class dll_export timer : public object {
170  std::chrono::steady_clock::time_point m_Begin;
171  std::chrono::steady_clock::time_point m_End;
172  bool m_is_running;
173  public:
174 
178  enum init_flag {
182  started
183  };
184  public:
185 
193 
197  ~timer(void);
198 
202  void start(void);
203 
208  const timer& stop(void);
209 
214  double seconds(void)const;
215 
220  double milliseconds(void)const;
221  // Internal
222  static clock_t machine_cycles(void);
223  };
224 
226  std::ostream& operator<<(std::ostream&, const timer&);
227 
228  class Initializer {
229  public:
230  Initializer() { ; }
231  virtual ~Initializer() { ; }
232  virtual void Initialize() { ; }
233  };
234 
235  class ref_count {
236  size_t m_ref_count;
237  public:
238  ref_count(void) :
239  m_ref_count(0) {
240  ;
241  }
242  void incr_ref(void) {
243  ++m_ref_count;
244  }
245  void decr_ref(void) {
246  tsa_assert(m_ref_count > 0);
247  --m_ref_count;
248  }
249  size_t num_ref(void) {
250  return m_ref_count;
251  }
252  };
253 
254  // internal
255  template<typename TYPE>
256  class dll_export singleton : public object {
257  tsa_declare_testable;
258  static std::mutex m_mutex;
259  public:
260  singleton() {}
261  ~singleton() {}
262  static TYPE* get(bool bCreate = true);
263  static void set(TYPE*);
264  static void reset(void);
265  private:
266  static TYPE* m_object_ptr;
267  };
268 
269  template<typename TYPE>
270  TYPE* singleton<TYPE>::m_object_ptr = nullptr;
271 
272  template<typename TYPE>
273  std::mutex singleton<TYPE>::m_mutex;
274 
275  template<typename TYPE>
276  TYPE* singleton<TYPE>::get(bool create_if_not_exist) {
277  std::lock_guard<std::mutex> lock(singleton<TYPE>::m_mutex);
278  if (m_object_ptr == nullptr && create_if_not_exist) {
279  m_object_ptr = (TYPE*) new TYPE();
280  tsa_assert(m_object_ptr != nullptr);
281  ((TYPE&)*m_object_ptr).Initialize();
282  }
283  return m_object_ptr;
284  }
285 
286  template<typename TYPE>
287  void singleton<TYPE>::set(TYPE* pObj) {
288  std::lock_guard<std::mutex> lock(singleton<TYPE>::m_mutex);
289  m_object_ptr = pObj;
290  }
291 
292  template<typename TYPE>
293  void singleton<TYPE>::reset() {
294  std::lock_guard<std::mutex> lock(singleton<TYPE>::m_mutex);
295  if (m_object_ptr) {
296  delete m_object_ptr;
297  m_object_ptr = nullptr;
298  }
299  }
300 
301  // Internal
302  class ASCII_LineGraph : public object {
303  tsa_declare_testable;
304  protected:
305  int m_nMarginLeft;
306  double m_dDataMax;
307  double m_dDataMin;
308  struct HL {
309  int nH;
310  int nL;
311  };
312  struct HLC {
313  double dH;
314  double dL;
315  };
316  double m_dLastClose;
317  std::vector<HLC> m_DataHLC;
318  std::vector<HL> m_BarArr;
319  std::vector<HL> m_TmpBarArr;
320  int m_nMatrixHeight;
321  int m_nMatrixWidth;
322  char* m_Matrix;
323  double m_dCellHeight;
324  int m_nYValueOfZero;
325  std::vector<size_t> m_yValues;
326  std::vector<string> m_yLegend;
327  char m_CloseChar;
328  char m_BarChar;
329  date_time m_tStart;
330  date_time m_tEnd;
331  bool m_bAllDaily;
332  string m_sName;
333  protected:
334  void ClearMatrix(void);
335  void ClearData(void);
336  void MakeYBarArray(void);
337  void FindMinMax(void);
338  void DeriveGraphMetrics(void);
339  int CalcYValue(double dataValue);
340  void SetPixels(void);
341  void SetAt(int x, int y, char _Val);
342  char at(int x, int y);
343  public:
344  ASCII_LineGraph(size_t height = 20, size_t width = 65);
345  virtual ~ASCII_LineGraph(void);
346  void SetBarChar(char close, char bar);
347  void AddBar(double high, double low, double close, const date_time& timestamp);
348  void AddDataItem(double close, const date_time& timestamp);
349  void SetName(const tsa::string& name);
350  void ProcessData(void);
351  void SetLeftMargin(size_t);
352  void Print(std::ostream& _s);
353  void SetData(std::vector<double>& _data);
354  };
355 
356  class dll_export TablePrinter : public object {
357  tsa_declare_testable;
358  public:
359  enum Allignment { Left, Right };
360  private:
361  struct Field {
362  string sDateFormat;
363  string sName;
364  type_t eType;
365  size_t nContentSize;
366  size_t precision;
367  string sContent;
368  Allignment eAllign;
369  bool bDateOnly;
370  };
371  std::vector<Field> m_Fields;
372  std::vector<string> m_Content;
373  size_t m_nRightCellBuffer;
374  size_t m_nLeftCellBuffer;
375  size_t GetNumFields(void)const;
376  string ConvertToString(size_t fieldIdx, const variant&)const;
377  bool m_nUseSeparator;
378  char m_nSeparatorChar;
379  bool m_LineAfterTitle;
380  size_t m_nNumRecPrinted;
381  bool m_bDrawGrid;
382  size_t m_nRecCnt;
383  size_t m_nSeparatorInterval;
384  size_t m_nHeaderReprintInterval;
385  bool m_bPrintHeader;
386  size_t m_LeftTableMargin;
387  bool m_bSeparateThousands;
388  bool m_bPrintBoolAsString;
389  bool m_bOverrideIndividualPrecision;
390  size_t m_nFPPrecision;
391  public:
392  static const size_t DEFAULT_PRECISION = 10;
393  public:
394  TablePrinter(void);
395  virtual ~TablePrinter(void);
396  void AddBoolField(const tsa::string& name, Allignment);
397  void AddLongField(const tsa::string& name, Allignment);
398  void AddStringField(const tsa::string& name, Allignment);
399  void AddDoubleField(const tsa::string& name, Allignment,
400  size_t precision = TablePrinter::DEFAULT_PRECISION);
401  void AddDateTimeField(const tsa::string& name, Allignment allign, bool dateOnly = false,
402  const tsa::string& format = "yyyy-mmm-dd");
403  void AddDateField(const tsa::string& name, Allignment allign, const tsa::string& format = "yyyy-mmm-dd");
404  void SetDrawBorders(bool);
405  void SetPrintBoolAsString(bool bFlag);
406  void SetSeparatorInterval(size_t);
407  void SetHeaderReprintInterval(size_t);
408  void SetCellBuffers(size_t left, size_t right);
409  void SetPrintHeader(bool);
410  void SetLeftTableMargin(size_t);
411  void SetSeparateThousands(bool);
412  void SetPrecision(size_t nPrecision);
413  void AnalyzeRecord(const std::vector<variant>& record);
414  void PrintHeader(std::ostream&, bool isReprint = false);
415  void PrintTopGridLine(std::ostream&, char c = '_');
416  void PrintBottomGridLine(std::ostream&, char c = '_');
417  void PrintRecord(const std::vector<variant>& record, std::ostream& stream,
418  const tsa::string& sSpecialEOLString = "");
419  };
420 } //tsa
421 
422 #endif
Namespace for the &#39;Trading System API&#39; library.
Definition: original1.TSA3Core.cpp:20
Start the timer immediately upon construction.
Definition: TSASupport.h:182
variant objects can represent values of different types.
Definition: TSAVariant.h:140
_value_types_type
Data type enumeration used throughout the library. Intended to be used via type_t.
Definition: TSATypeDef.h:166
Construct the timer object, but do not start timing.
Definition: TSASupport.h:180
Parent class for many library classes.
Definition: TSATypeDef.h:462
A timer.
Definition: TSASupport.h:169
Class representing a database record.
Definition: TSADBRecord.h:52
init_flag
Timer constructor flag.
Definition: TSASupport.h:178
Class representing a gregorian-date and time-of-day combination. The time component has microsecond r...
Definition: TSATime.h:428