fix8  version 1.4.0
Open Source C++ FIX Framework
hftest.cpp
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------------------
2 /*
3 
4 Fix8 is released under the GNU LESSER GENERAL PUBLIC LICENSE Version 3.
5 
6 Fix8 Open Source FIX Engine.
7 Copyright (C) 2010-16 David L. Dight <fix@fix8.org>
8 
9 Fix8 is free software: you can redistribute it and / or modify it under the terms of the
10 GNU Lesser General Public License as published by the Free Software Foundation, either
11 version 3 of the License, or (at your option) any later version.
12 
13 Fix8 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 
16 You should have received a copy of the GNU Lesser General Public License along with Fix8.
17 If not, see <http://www.gnu.org/licenses/>.
18 
19 BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO
20 THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
21 COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
22 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
24 THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
25 YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
26 
27 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
28 HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
29 ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
30 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
31 NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
32 THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
33 HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 
35 */
36 
37 //-----------------------------------------------------------------------------------------
89 //-----------------------------------------------------------------------------------------
90 #include <iostream>
91 #include <memory>
92 #include <fstream>
93 #include <iomanip>
94 #include <sstream>
95 #include <vector>
96 #include <map>
97 #include <list>
98 #include <set>
99 #include <iterator>
100 #include <algorithm>
101 #include <typeinfo>
102 #ifdef _MSC_VER
103 #include <signal.h>
104 #include <conio.h>
105 #else
106 #include <sys/ioctl.h>
107 #include <signal.h>
108 #include <termios.h>
109 #endif
110 
111 #include <errno.h>
112 #include <string.h>
113 
114 // f8 headers
115 #include <fix8/f8includes.hpp>
116 
117 #ifdef FIX8_HAVE_GETOPT_H
118 #include <getopt.h>
119 #endif
120 
121 #include <fix8/usage.hpp>
122 #include "Perf_types.hpp"
123 #include "Perf_router.hpp"
124 #include "Perf_classes.hpp"
125 
126 #include "hftest.hpp"
127 
128 //-----------------------------------------------------------------------------------------
129 using namespace std;
130 
131 //-----------------------------------------------------------------------------------------
132 void print_usage();
133 const string GETARGLIST("hl:svqc:R:S:rb:p:u:o");
134 bool term_received(false);
135 unsigned batch_size(1000), preload_count(0), update_count(5000);
136 
137 //-----------------------------------------------------------------------------------------
139 {
140  { { 'n', "Send a NewOrderSingle msg" }, &MyMenu::new_order_single },
141  { { 'p', "Preload n NewOrderSingle msgs" }, &MyMenu::preload_new_order_single },
142  { { 'b', "Batch preload and send n NewOrderSingle msgs" }, &MyMenu::batch_preload_new_order_single },
143  { { 'N', "Send n NewOrderSingle msgs" }, &MyMenu::multi_new_order_single },
144  { { 'a', "Send all Preloaded NewOrderSingle msgs" }, &MyMenu::send_all_preloaded },
145  { { '?', "Help" }, &MyMenu::help },
146  { { 'l', "Logout" }, &MyMenu::do_logout },
147  { { 'x', "Exit" }, &MyMenu::do_exit },
148 };
149 
150 bool quiet(true);
151 
152 //-----------------------------------------------------------------------------------------
153 void sig_handler(int sig)
154 {
155  switch (sig)
156  {
157  case SIGTERM:
158  case SIGINT:
159 #ifndef _MSC_VER
160  case SIGQUIT:
161 #endif
162  term_received = true;
163  signal(sig, sig_handler);
164  break;
165  default:
166  cerr << sig << endl;
167  break;
168  }
169 }
170 
171 //-----------------------------------------------------------------------------------------
172 int main(int argc, char **argv)
173 {
174  int val;
175  bool server(false), once(false), reliable(false);
176  string clcf;
177  unsigned next_send(0), next_receive(0);
178 
179 #ifdef FIX8_HAVE_GETOPT_LONG
180  option long_options[]
181  {
182  { "help", 0, 0, 'h' },
183  { "version", 0, 0, 'v' },
184  { "once", 0, 0, 'o' },
185  { "log", 1, 0, 'l' },
186  { "config", 1, 0, 'c' },
187  { "server", 0, 0, 's' },
188  { "batch", 1, 0, 'b' },
189  { "send", 1, 0, 'S' },
190  { "receive", 1, 0, 'R' },
191  { "quiet", 0, 0, 'q' },
192  { "reliable", 0, 0, 'r' },
193  { "preload", 1, 0, 'p' },
194  { "update", 1, 0, 'u' },
195  { 0 },
196  };
197 
198  while ((val = getopt_long (argc, argv, GETARGLIST.c_str(), long_options, 0)) != -1)
199 #else
200  while ((val = getopt (argc, argv, GETARGLIST.c_str())) != -1)
201 #endif
202  {
203  switch (val)
204  {
205  case 'v':
206  cout << argv[0] << " for " FIX8_PACKAGE " version " FIX8_VERSION << endl;
207  cout << "Released under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3. See <http://fsf.org/> for details." << endl;
208  return 0;
209  case ':': case '?': return 1;
210  case 'h': print_usage(); return 0;
211  case 'l': FIX8::GlobalLogger::set_global_filename(optarg); break;
212  case 'c': clcf = optarg; break;
213  case 'b': batch_size = stoul(optarg); break;
214  case 'p': preload_count = stoul(optarg); break;
215  case 'u': update_count = stoul(optarg); break;
216  case 's': server = true; break;
217  case 'o': once = true; break;
218  case 'S': next_send = stoul(optarg); break;
219  case 'R': next_receive = stoul(optarg); break;
220  case 'q': quiet = false; break;
221  case 'r': reliable = true; break;
222  default: break;
223  }
224  }
225 
226  RandDev::init();
227 
228  signal(SIGTERM, sig_handler);
229  signal(SIGINT, sig_handler);
230 #ifndef _MSC_VER
231  signal(SIGQUIT, sig_handler);
232 #endif
233 
234  try
235  {
236  const string conf_file(server ? clcf.empty() ? "hf_server.xml" : clcf : clcf.empty() ? "hf_client.xml" : clcf);
237 
238  if (server)
239  {
240  unique_ptr<FIX8::ServerSessionBase> ms(new FIX8::ServerSession<hf_session_server>(FIX8::TEX::ctx(), conf_file, "TEX1"));
241 
242  XmlElement::XmlSet eset;
243 
244  for (unsigned scnt(0); !term_received; )
245  {
246  if (!ms->poll())
247  continue;
248  unique_ptr<FIX8::SessionInstanceBase> inst(ms->create_server_instance());
249  if (!quiet)
250  inst->session_ptr()->control() |= FIX8::Session::print;
251  ostringstream sostr;
252  sostr << "client(" << ++scnt << ") connection established.";
253  FIX8::GlobalLogger::log(sostr.str());
254  const FIX8::ProcessModel pm(ms->get_process_model(ms->_ses));
255  inst->start(pm == FIX8::pm_pipeline, next_send, next_receive);
256  cout << (pm == FIX8::pm_pipeline ? "Pipelined" : "Threaded") << " mode." << endl;
257  if (inst->session_ptr()->get_connection()->is_secure())
258  cout << "Session is secure (SSL)" << endl;
259  if (pm != FIX8::pm_pipeline)
260  while (!inst->session_ptr()->is_shutdown())
261  FIX8::hypersleep<FIX8::h_milliseconds>(100);
262  cout << "Session(" << scnt << ") finished." << endl;
263  inst->stop();
264 #if defined FIX8_CODECTIMING
265  FIX8::Message::report_codec_timings("server");
266 #endif
267  if (once)
268  break;
269  }
270  }
271  else
272  {
273  unique_ptr<FIX8::ClientSessionBase>
274  mc(reliable ? new FIX8::ReliableClientSession<hf_session_client>(FIX8::TEX::ctx(), conf_file, "DLD1")
275  : new FIX8::ClientSession<hf_session_client>(FIX8::TEX::ctx(), conf_file, "DLD1"));
276  if (!quiet)
277  mc->session_ptr()->control() |= FIX8::Session::print;
278 
279  const FIX8::ProcessModel pm(mc->get_process_model(mc->_ses));
280  if (!reliable)
281  mc->start(false, next_send, next_receive, mc->session_ptr()->get_login_parameters()._davi());
282  else
283  mc->start(false, next_send, next_receive);
284 
285  MyMenu mymenu(*mc->session_ptr(), 0, cout);
286  cout << endl << "Menu started. Press '?' for help..." << endl << endl;
287  if (mc->session_ptr()->get_connection()->is_secure())
288  cout << "Session is secure (SSL)" << endl;
289  if (preload_count)
290  mymenu.preload_new_order_single();
291  char ch;
292  mymenu.get_tty().set_raw_mode();
293  if (pm == FIX8::pm_coro)
294  {
295  cout << "Coroutine mode." << endl;
296  fd_set rfds;
297  timeval tv {};
298 
299  while (!term_received)
300  {
301  mc->session_ptr()->get_connection()->reader_execute();
302  char ch(0);
303  FD_ZERO(&rfds);
304  FD_SET(0, &rfds);
305 #ifdef _MSC_VER
306  if (kbhit())
307  {
308  ch = getch();
309 #else
310  if (select(1, &rfds, 0, 0, &tv) > 0)
311  {
312  if (read (0, &ch, 1) < 0)
313  break;
314 #endif
315  if (ch == 'a')
316  {
317  cout << "Sending messages..." << endl;
318  coroutine coro;
319  while(mymenu.send_all_preloaded(coro, mc->session_ptr()))
320  mc->session_ptr()->get_connection()->reader_execute();
321  }
322  else if (ch == 0x3 || !mymenu.process(ch))
323  break;
324  }
325  }
326  }
327  else
328  {
329  cout << (pm == FIX8::pm_pipeline ? "Pipelined" : "Threaded") << " mode." << endl;
330  while(!mymenu.get_istr().get(ch).bad() && !term_received && ch != 0x3 && mymenu.process(ch))
331  ;
332  }
333  cout << endl;
334 #if defined FIX8_CODECTIMING
335  FIX8::Message::report_codec_timings("client");
336 #endif
337  if (!mc->session_ptr()->is_shutdown())
338  mc->session_ptr()->stop();
339 
340  mymenu.get_tty().unset_raw_mode();
341  }
342  }
343  catch (FIX8::f8Exception& e)
344  {
345  cerr << "exception: " << e.what() << endl;
346  }
347  catch (exception& e) // also catches Poco::Net::NetException
348  {
349  cerr << "exception: " << e.what() << endl;
350  }
351 
352  if (term_received)
353  cout << "terminated." << endl;
354  return 0;
355 }
356 
357 //-----------------------------------------------------------------------------------------
359 {
360  unsigned num(preload_count);
361  if (!num)
362  {
363  cout << "Enter number of NewOrderSingle msgs to batch preload:";
364  cout.flush();
365  _tty.unset_raw_mode();
366  cin >> num;
367  _tty.set_raw_mode();
368  }
369  while (num > 0)
370  {
371  unsigned cnt(0);
372  for (; cnt < num && cnt < batch_size; ++cnt)
373  {
374  static unsigned oid(10000);
375  ostringstream oistr;
376  oistr << "ord" << ++oid << '-' << num;
377 
379  *ptr << new FIX8::TEX::Symbol("BHP")
385  << new FIX8::TEX::ClOrdID(oistr.str())
386  << new FIX8::TEX::Price(1. + RandDev::getrandom(500.), 3)
387  << new FIX8::TEX::OrderQty(1 + RandDev::getrandom(10000));
388 
389 #if defined FIX8_PREENCODE_MSG_SUPPORT
390  ptr->preencode();
391 #endif
392  _session.push(ptr);
393  }
394  cout << _session.cached() << " NewOrderSingle msgs preloaded." << endl;
395  num -= cnt;
396  send_all_preloaded();
397  }
398 
399  return true;
400 }
401 
402 //-----------------------------------------------------------------------------------------
404 {
405  cout << "Enter number of NewOrderSingle msgs to send:";
406  cout.flush();
407  unsigned num(0);
408  _tty.unset_raw_mode();
409  cin >> num;
410  _tty.set_raw_mode();
411  for (unsigned ii(0); ii < num; ++ii)
412  new_order_single();
413  cout << endl << num << " NewOrderSingle msgs sent" << endl;
414 
415  return true;
416 }
417 
418 //-----------------------------------------------------------------------------------------
420 {
421  static unsigned oid(0);
422  ostringstream oistr;
423  oistr << "ord" << ++oid;
424 
426  *nos << new FIX8::TEX::TransactTime
427  << new FIX8::TEX::OrderQty(1 + RandDev::getrandom(10000))
428  << new FIX8::TEX::Price(1. + RandDev::getrandom(500.))
429  << new FIX8::TEX::ClOrdID(oistr.str())
430  << new FIX8::TEX::Symbol("BHP")
435 
436  _session.send(nos);
437 
438  return true;
439 }
440 
441 //-----------------------------------------------------------------------------------------
443 {
444  const unsigned tosend(_session.size());
445  cout << "Sending " << tosend << " NewOrderSingle msgs ..." << flush;
446  unsigned snt(0);
447  while (_session.cached())
448  {
449  FIX8::TEX::NewOrderSingle *ptr(_session.pop());
450  if (!ptr)
451  break;
452  _session.send(ptr);
453  if (++snt % update_count == 0)
454  {
455  cout << '\r' << snt << " NewOrderSingle msgs sent ";
456  cout.flush();
457  }
458  }
459  cout << endl << snt << " NewOrderSingle msgs sent." << endl;
460  return true;
461 }
462 
463 //-----------------------------------------------------------------------------------------
465 {
466  unsigned snt(0);
468 
469  reenter(coro)
470  {
471  ses->get_connection()->set_tcp_cork_flag(true);
472  while (_session.cached())
473  {
474  if (ses->get_connection()->writer_poll())
475  {
476  if (!(ptr = _session.pop()))
477  break;
478  _session.send(ptr);
479  if (++snt % batch_size)
480  continue;
481  }
482  ses->get_connection()->set_tcp_cork_flag(false);
483  coro_yield;
484  }
485  }
486  ses->get_connection()->set_tcp_cork_flag(false);
487  return _session.cached();
488 }
489 
490 //-----------------------------------------------------------------------------------------
492 {
493  cout << endl;
494  if (_session.size())
495  cout << _session.size() << " NewOrderSingle msgs currently preloaded." << endl;
496  unsigned num(preload_count);
497  if (!num)
498  {
499  cout << "Enter number of NewOrderSingle msgs to preload:";
500  cout.flush();
501  _tty.unset_raw_mode();
502  cin >> num;
503  _tty.set_raw_mode();
504  }
505  else
506  cout << "loading..." << endl;
507  for (unsigned ii(0); ii < num; ++ii)
508  {
509  static unsigned oid(10000);
510  ostringstream oistr;
511  oistr << "ord" << ++oid << '-' << num;
512 
514 
515  *ptr << new FIX8::TEX::Symbol("BHP")
521  << new FIX8::TEX::Price(1. + RandDev::getrandom(500.), 3) // precision=3
522  << new FIX8::TEX::ClOrdID(oistr.str())
523  << new FIX8::TEX::OrderQty(1 + RandDev::getrandom(10000));
524 #if defined FIX8_PREENCODE_MSG_SUPPORT
525  ptr->preencode(); // pre-encode message payload (not header or trailer)
526 #endif
527  _session.push(ptr);
528  }
529 
530  cout << _session.size() << " NewOrderSingle msgs preloaded." << endl;
531 
532  return true;
533 }
534 
535 //-----------------------------------------------------------------------------------------
536 bool MyMenu::help()
537 {
538  get_ostr() << endl;
539  get_ostr() << "Key\tCommand" << endl;
540  get_ostr() << "===\t=======" << endl;
541  for (const auto& pp : _handlers)
542  get_ostr() << pp.first._key << '\t' << pp.first._help << endl;
543  get_ostr() << endl;
544  return true;
545 }
546 
547 //-----------------------------------------------------------------------------------------
548 bool MyMenu::do_logout()
549 {
550  if (!_session.is_shutdown())
551  _session.send(new FIX8::TEX::Logout);
552  FIX8::hypersleep<FIX8::h_seconds>(2);
553  return false; // will exit
554 }
555 
556 //-----------------------------------------------------------------------------------------
558 {
559  UsageMan um("hftest", GETARGLIST, "");
560  um.setdesc("hftest -- f8 HF test client/server");
561  um.add('s', "server", "run in server mode (default client mode)");
562  um.add('h', "help", "help, this screen");
563  um.add('v', "version", "print version then exit");
564  um.add('l', "log", "global log filename");
565  um.add('c', "config", "xml config (default: hf_client.xml or hf_server.xml)");
566  um.add('o', "once", "for server, allow one client session then exit");
567  um.add('q', "quiet", "do not print fix output (default yes)");
568  um.add('b', "batch", "if using batch send, number of messages in each batch (default 1000)");
569  um.add('p', "preload", "if batching or preloading, default number of messages to create");
570  um.add('R', "receive", "set next expected receive sequence number");
571  um.add('S', "send", "set next send sequence number");
572  um.add('r', "reliable", "start in reliable mode");
573  um.add('u', "update", "message count update frequency (default 5000)");
574  um.print(cerr);
575 }
576 
577 //-----------------------------------------------------------------------------------------
578 //-----------------------------------------------------------------------------------------
579 bool hf_session_client::handle_application(const unsigned seqnum, const FIX8::Message *&msg)
580 {
581  return enforce(seqnum, msg) || msg->process(_router);
582 }
583 
584 //-----------------------------------------------------------------------------------------
586 {
587  static unsigned oid(0), eoid(0);
590  msg->get(qty);
591  msg->get(price);
592 
594  msg->copy_legal(er);
595 
596  ostringstream oistr;
597  oistr << "ord" << ++oid;
598  *er << new FIX8::TEX::OrderID(oistr.str())
600  unsigned ordResult(RandDev::getrandom(3));
601  switch (ordResult)
602  {
603  default:
604  case 0:
606  break;
607  case 1:
609  break;
610  case 2:
612  break;
613  }
614 
615  *er << new FIX8::TEX::LeavesQty(qty())
616  << new FIX8::TEX::CumQty(0.)
617  << new FIX8::TEX::AvgPx(0.)
618  << new FIX8::TEX::LastCapacity('5')
619  << new FIX8::TEX::ReportToExch('Y')
621  << new FIX8::TEX::ExecID(oistr.str());
622 
623  _session.send(er);
624 
625  if (ordResult == 0)
626  {
627  unsigned remaining_qty(qty()), cum_qty(0);
628  while (remaining_qty > 0)
629  {
630  unsigned trdqty(1 + RandDev::getrandom(remaining_qty));
631  remaining_qty -= trdqty;
632  cum_qty += trdqty;
634  msg->copy_legal(ner);
635  ostringstream eistr;
636  eistr << "exec" << ++eoid;
637 
638  *ner << new FIX8::TEX::ExecID(eistr.str())
639  << new FIX8::TEX::OrderID(oistr.str())
642  << new FIX8::TEX::LeavesQty(remaining_qty)
643  << new FIX8::TEX::CumQty(cum_qty)
645  << new FIX8::TEX::AvgPx(price());
646 
647  _session.send(ner);
648  }
649  }
650 
651  return true;
652 }
653 
654 //-----------------------------------------------------------------------------------------
656 {
657  static int exrecv(0);
658  if (++exrecv % update_count == 0)
659  {
660  cout << '\r' << exrecv << " ExecutionReport msgs received ";
661  cout.flush();
662  }
663  return true;
664 }
665 
666 //-----------------------------------------------------------------------------------------
667 bool hf_session_server::handle_application(const unsigned seqnum, const FIX8::Message *&msg)
668 {
669  return enforce(seqnum, msg) || msg->process(_router);
670 }
671 
void sig_handler(int sig)
Definition: hftest.cpp:153
static void init()
Initialise the random number generator.
Definition: hftest.hpp:205
bool handle_application(const unsigned seqnum, const FIX8::Message *&msg)
Definition: hftest.cpp:579
Connection * get_connection()
Definition: session.hpp:665
Field< Qty, 14 > CumQty
bool do_logout()
Definition: harness.cpp:367
Field< char, 54 > Side
const char HandlInst_AUTOMATED_EXECUTION_ORDER_PRIVATE_NO_BROKER_INTERVENTION('1')
static const Handlers _handlers
Definition: hftest.hpp:171
virtual bool operator()(const FIX8::TEX::ExecutionReport *msg)
Definition: hftest.cpp:655
const char ExecTransType_NEW('0')
Fix8 Base Session. User sessions are derived from this class.
Definition: session.hpp:394
unsigned preload_count(0)
bool preload_new_order_single()
Definition: hftest.cpp:491
const char TimeInForce_FILL_OR_KILL('4')
Field< char, 59 > TimeInForce
const string GETARGLIST("hl:svqc:R:S:rb:p:u:o")
static T getrandom(const T range=0)
Definition: hftest.hpp:219
bool send_all_preloaded()
Definition: hftest.cpp:442
bool add(const char sw, const std::string &lsw, const std::string &help)
Definition: usage.hpp:73
const char Side_BUY('1')
Field< char, 39 > OrdStatus
ExecutionReport (8), application, 326 fields, 16 groups.
Field< Boolean, 113 > ReportToExch
#define FIX8_PACKAGE
Definition: f8config.h:601
Field< price, 44 > Price
F8API unsigned copy_legal(MessageBase *to, bool force=false) const
Definition: message.cpp:275
Client wrapper.
Logout (5), admin, 3 fields, 0 groups.
Field< char, 40 > OrdType
bool new_order_single()
Definition: hftest.cpp:419
ProcessModel
Supported session process models.
Definition: f8types.hpp:56
unsigned next_receive(0)
void print_usage()
Definition: hftest.cpp:557
const char OrdStatus_FILLED('2')
bool get(T &to) const
Definition: message.hpp:671
bool handle_application(const unsigned seqnum, const FIX8::Message *&msg)
Definition: hftest.cpp:667
unsigned next_send(0)
bool term_received(false)
const F8MetaCntx & ctx()
Compiler generated metadata object, accessed through this function.
Base exception class.
Definition: f8exception.hpp:49
NewOrderSingle (D), application, 243 fields, 11 groups.
void setdesc(const std::string &desc)
Definition: usage.hpp:91
bool do_exit()
Definition: hftest.hpp:194
Field< char, 21 > HandlInst
void print(std::ostream &os) const
Definition: usage.hpp:95
bool quiet(true)
const char OrdType_LIMIT('2')
Field< f8String, 11 > ClOrdID
Definition: Myfix_types.hpp:93
std::map< const MenuItem, bool(MyMenu::*)(), MenuItem > Handlers
Definition: hftest.hpp:170
virtual bool operator()(const FIX8::TEX::NewOrderSingle *msg)
Definition: hftest.cpp:585
virtual bool process(Router &rt) const
Definition: message.hpp:1147
bool multi_new_order_single()
Definition: hftest.cpp:403
Field< char, 20 > ExecTransType
Definition: Perf_types.hpp:122
std::set< const XmlElement *, EntityOrderComp > XmlSet
Definition: xml.hpp:74
Simple menu system that will work with most term types.
Definition: hftest.hpp:151
A complete Fix message with header, body and trailer.
Definition: message.hpp:1058
#define reenter(c)
Definition: yield.hpp:12
Field< price, 6 > AvgPx
Definition: Myfix_types.hpp:83
int main(int argc, char **argv)
Definition: hftest.cpp:172
const char OrdStatus_CANCELED('4')
Field template. There will ONLY be partial template specialisations of this template.
Definition: field.hpp:256
Field< char, 29 > LastCapacity
const char OrdStatus_PARTIALLY_FILLED('1')
void set_tcp_cork_flag(bool way) const
Definition: connection.hpp:661
bool writer_poll(const Poco::Timespan &ts=Poco::Timespan()) const
Definition: connection.hpp:688
Field< f8String, 37 > OrderID
unsigned update_count(5000)
Field< Qty, 38 > OrderQty
static void set_global_filename(const std::string &from)
Definition: logger.hpp:492
#define FIX8_VERSION
Definition: f8config.h:742
Field< f8String, 55 > Symbol
const char OrdStatus_REJECTED('8')
const char OrdStatus_NEW('0')
#define coro_yield
Definition: yield.hpp:16
size_t size() const
Definition: message.hpp:451
const char * what() const
Definition: f8exception.hpp:85
unsigned batch_size(1000)
const char ExecType_NEW('0')
bool help()
Definition: harness.cpp:345
bool batch_preload_new_order_single()
Definition: hftest.cpp:358
static bool log(const std::string &what, Logger::Level lev=Logger::Info, const char *fl=nullptr, unsigned int val=0)
Definition: logger.hpp:501
Field< Qty, 151 > LeavesQty
Convenient program help/usage wrapper. Generates a standardised usage message.
Definition: usage.hpp:42
Reliable Client wrapper. This client attempts to recover from disconnects and login rejects...
Field< f8String, 17 > ExecID
fp_type price
Definition: field.hpp:2024