1/*
2 * Legal Notice
3 *
4 * This document and associated source code (the "Work") is a part of a
5 * benchmark specification maintained by the TPC.
6 *
7 * The TPC reserves all right, title, and interest to the Work as provided
8 * under U.S. and international laws, including without limitation all patent
9 * and trademark rights therein.
10 *
11 * No Warranty
12 *
13 * 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION
14 * CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE
15 * AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER
16 * WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
17 * INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES,
18 * DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
19 * PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF
20 * WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE.
21 * ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT,
22 * QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT
23 * WITH REGARD TO THE WORK.
24 * 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO
25 * ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE
26 * COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS
27 * OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT,
28 * INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY,
29 * OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT
30 * RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD
31 * ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
32 *
33 * Contributors
34 * - Sergey Vasilevskiy
35 * - Doug Johnson
36 */
37
38/*
39 * Class that generates trades and holdings for a given set
40 * of customers. It maintains the proper holding information
41 * for every customer while the trades are being generated.
42 *
43 * TRADE, TRADE_HISTORY, CASH_TRANSACTION, SETTLEMENT,
44 * HOLDING, HOLDING_HISTORY rows are generated by this class.
45 *
46 */
47
48#ifndef TRADE_GEN_H
49#define TRADE_GEN_H
50
51#include <queue>
52#include "utilities/EGenStandardTypes.h"
53#include "utilities/Money.h"
54#include "MEESecurity.h"
55#include "CustomerAccountsAndPermissionsTable.h"
56#include "AddressTable.h"
57#include "CustomerTable.h"
58#include "CustomerTaxRateTable.h"
59#include "CustomerSelection.h"
60#include "HoldingsAndTradesTable.h"
61#include "Brokers.h"
62#include "SecurityTable.h"
63#include "Person.h"
64#include "input/DataFileManager.h"
65#include "StatusTypeIDs.h"
66
67using namespace std;
68
69namespace TPCE {
70
71// Maximum number of HOLDING_HISTORY rows that can be output
72// for one completed trade.
73// Determined by the maximum number of holdings that a trade
74// can modify. The maximum number would be a trade with
75// the biggest possible quantity modifying holdings each having
76// the smallest possible quantity.
77//
78const int iMaxHoldingHistoryRowsPerTrade = 800 / 100;
79
80// Incomplete trade information generated
81// at Trade Order time.
82//
83typedef struct TTradeInfo {
84 TTrade iTradeId;
85 eTradeTypeID eTradeType; // integer representation of the TRADE row T_TT_ID
86 eStatusTypeID eTradeStatus; // integer representation of the TRADE row T_ST_ID
87 double PendingTime; // seconds from StartTime; only for limit orders
88 double SubmissionTime; // seconds from StartTime
89 double CompletionTime; // seconds from StartTime
90 TIdent iSymbolIndex; // stock symbol index in the input flat file
91 UINT iSymbolIndexInAccount; // stock symbol index in the account basket
92 int iTradeQty; // number of shares in the trade
93 CMoney fBidPrice; // bid price for market orders or limit price for limit ones
94 CMoney fTradePrice; // price that the trade completed at
95 TIdent iCustomer; // customer executing this trade
96 eCustomerTier iCustomerTier; // customer tier for the customer executing this trade
97 TIdent iCustomerAccount; // customer account in which the trade executes
98 bool bIsLifo; // needed to update holdings
99} * PTradeInfo;
100
101// Information about completed trade that is generated once
102// for performance
103typedef struct TAdditionalTradeInfo {
104 // Current value of trade's positions that are being closed
105 //
106 CMoney fBuyValue;
107 // Value of trade's positions when they were opened
108 //
109 CMoney fSellValue;
110
111 // Broker id of the account for the current completed trade
112 //
113 TIdent iCurrentBrokerId;
114
115 eTaxStatus eAccountTaxStatus;
116
117 // These fields are needed for correcteness (pricing consistency).
118 // They need to be kept in CMoney and only converted to double
119 // before copying them into table row structures.
120 //
121 CMoney Commission;
122 CMoney Charge;
123 CMoney Tax;
124 CMoney SettlementAmount;
125} * PAdditionalTradeInfo;
126
127// Customer holding information
128// to be able to generate HOLDING table after all trades
129// have been generated.
130//
131typedef struct THoldingInfo {
132 TTrade iTradeId;
133 int iTradeQty;
134 CMoney fTradePrice;
135 CDateTime BuyDTS;
136 TIdent iSymbolIndex; // stock symbol index in the input flat file - stored
137 // for performance
138} * PHoldingInfo;
139
140// Trade-related table rows.
141// HOLDING row is ommitted because it is contained in
142// a separate variable.
143//
144typedef struct TTradeRow {
145 TRADE_ROW m_Trade; // for the Trade table
146 TRADE_REQUEST_ROW m_TradeRequest; // for the Trade Requests table
147 TRADE_HISTORY_ROW m_TradeHistory[3]; // for the Trade History table
148 SETTLEMENT_ROW m_Settlement; // for the Settlement table
149 CASH_TRANSACTION_ROW m_CashTransaction; // for the Cash Transaction table
150 HOLDING_HISTORY_ROW m_HoldingHistory[iMaxHoldingHistoryRowsPerTrade];
151} * PTradeRow;
152
153// Container to store holdings
154//
155typedef list<THoldingInfo> THoldingList;
156typedef THoldingList TCustomerHoldingArray[iMaxSecuritiesPerAccount];
157
158class CTradeGen {
159 // RNG class for generation of row data
160 //
161 CRandom m_rnd;
162
163 // Class used to get address information for a customer
164 // to properly calculate tax on a trade
165 //
166 CAddressTable m_AddressTable;
167
168 // Class used to select a random customer for whom to perform a trade.
169 //
170 CCustomerSelection m_CustomerSelection;
171
172 // Class used to get CUSTOMER table information for a specific customer
173 //
174 CCustomerTable m_CustomerTable;
175
176 // Class used to calculate T_TAX for the TRADE table
177 //
178 CCustomerTaxRateTable m_CustTaxrateTable;
179
180 // Class used to get customer account information.
181 //
182 CCustomerAccountsAndPermissionsTable m_CustomerAccountTable;
183
184 // Class used in determining the basket of securities for an account
185 //
186 CHoldingsAndTradesTable m_HoldingTable;
187
188 // Class used to generate BROKER table (with consistent YTD columns)
189 //
190 CBrokersTable m_BrokerTable;
191
192 // Class used to get S_NAME for cash transaction descriptions
193 //
194 CSecurityTable m_SecurityTable;
195
196 // Class to get the first and last names of a customer
197 //
198 CPerson m_Person;
199
200 // Input files for character data generation.
201 //
202 const CCompanyFile &m_CompanyFile;
203 const CSecurityFile &m_SecurityFile;
204 const ChargeDataFile_t &m_ChargeFile; // CHARGE table from the flat file
205 const CommissionRateDataFile_t &m_CommissionRateFile; // COMMISSION_RATE table from the flat file
206 const StatusTypeDataFile_t &m_StatusTypeFile; // STATUS_TYPE table from the flat file
207 const TradeTypeDataFile_t &m_TradeTypeFile; // TRADE_TYPE table from the flat file
208 const ExchangeDataFile_t &m_ExchangeFile; // EXCHANGE table from the flat file
209
210 // The first customer to generate for this class instance
211 //
212 TIdent m_iStartFromCustomer;
213 // First account of the StartFromCustomer
214 //
215 TIdent m_iStartFromAccount;
216 // Number of customers for this class instance
217 //
218 TIdent m_iCustomerCount;
219 // Total number of customers in the database
220 //
221 TIdent m_iTotalCustomers;
222 // Number of customers in one load unit
223 //
224 int m_iLoadUnitSize;
225 // Number of accounts for customers in one load unit
226 //
227 int m_iLoadUnitAccountCount;
228 // Number of customers for 1 tpsE
229 //
230 int m_iScaleFactor;
231 // Number of hours of initial trades to generate
232 //
233 int m_iHoursOfInitialTrades;
234
235 // Average number of seconds between two consecutive trades
236 //
237 double m_fMeanTimeBetweenTrades;
238
239 // Mean delay between Pending and Submission times
240 // for an immediatelly triggered (in-the-money) limit order.
241 //
242 double m_fMeanInTheMoneySubmissionDelay;
243
244 // Time at which to start trade timestamps (time 0 or StartTime).
245 // Not changed during the class lifetime.
246 //
247 // This is the submission (or pending) time of the first trade.
248 //
249 CDateTime m_StartTime;
250
251 // Current Trade Order time in the simulated
252 // time sequence (seconds from StartTime).
253
254 // When this time is further than
255 // the priority queue's front, incomplete trades
256 // are removed from the priority queue and completed.
257 //
258 // If this time is before the priority queue front
259 // time, new incomplete trades are placed on the queue
260 // and this time is incremented.
261 //
262 double m_CurrentSimulatedTime;
263
264 // Priority queue that contains incomplete trades
265 // ordered by their completion time. The queue's
266 // front contains trade with the earliest completion
267 // time.
268 //
269 // Template default is to return the biggest value,
270 // but we need the smallest (earliest) one. This is
271 // why we specify greater<> for the template comparison
272 // parameter instead of the default less<>
273 priority_queue<TTradeInfo, vector<TTradeInfo>, greater<TTradeInfo>> m_CurrentTrades;
274
275 // Number of trades completed up to now.
276 // Does not include aborted trades.
277 //
278 TTrade m_iCurrentCompletedTrades;
279
280 // Number of total trades needed to generate.
281 // Does not include aborted trades.
282 //
283 TTrade m_iTotalTrades;
284
285 // Number of trades initiated up to now. Includes aborted
286 // trades.
287 // Needed to calculate when to abort a trade at Trade Order time.
288 //
289 TTrade m_iCurrentInitiatedTrades;
290
291 // Number of trades in an 8-hour workday.
292 // Needed to know when to move trading time to the next day.
293 //
294 int m_iTradesPerWorkDay;
295
296 // 3-dimensional array of double-linked lists each containing
297 // one customer holding information.
298 //
299 // The array is indexed as follows:
300 // [AccountId][SecurityIndexWithinAccount]
301 //
302 // There is no need to index on customer id since the account
303 // id is unique across the universe of all customers
304 //
305 TCustomerHoldingArray *m_pCustomerHoldings;
306
307 // Structure to contain incomplete, but essential
308 // trade information generated at Trade Order time.
309 //
310 TTradeInfo m_NewTrade;
311
312 // Structure to contain trade non-essential information
313 // frequently used at Trade Result time.
314 //
315 TAdditionalTradeInfo m_CompletedTradeInfo;
316
317 // Structure to contain current trade and holding
318 // table rows.
319 // Filled in GenerateNextTrade() for trade-related
320 // tables and in GenerateNextHolding for
321 // holding-related tables.
322 //
323 TTradeRow m_TradeRow;
324 HOLDING_ROW m_HoldingRow;
325
326 // Structure to contain HOLDING_SUMMARY rows.
327 // Filled in GenerateNextHoldingSummaryRow.
328 HOLDING_SUMMARY_ROW m_HoldingSummaryRow;
329
330 // Number of Trade History rows for the current trade in m_TradeRow.
331 //
332 int m_iTradeHistoryRowCount;
333
334 // Number of Cash Transaction rows for the current trade in m_TradeRow.
335 //
336 int m_iCashTransactionRowCount;
337
338 // Number of Settlement rows for the current trade in m_TradeRow.
339 //
340 int m_iSettlementRowCount;
341
342 // Number of Holding History rows. May be more than one
343 // if the trade modifies more than one holding.
344 //
345 int m_iHoldingHistoryRowCount;
346
347 // Security price emulation
348 CMEESecurity m_MEESecurity;
349
350 // Account, security index, and security holding
351 // to use in GenerateNextHolding() to return the next holding.
352 //
353 int m_iCurrentAccountForHolding;
354 int m_iCurrentSecurityForHolding; // index within the account (not input
355 // file)
356 list<THoldingInfo>::iterator m_pCurrentSecurityHolding;
357
358 // Account index and security index,
359 // used in GenerateNextHoldingSummaryRecord().
360 //
361 int m_iCurrentAccountForHoldingSummary; // index
362 int m_iCurrentSecurityForHoldingSummary; // index
363
364 // Trade ID for the last generated trade.
365 // Positioned at the correct trade id at start.
366 //
367 TTrade m_iCurrentTradeId;
368
369 // Current load unit number
370 //
371 int m_iCurrentLoadUnit;
372
373 ///////////////////////////////////////////////////
374 // Functions
375 ///////////////////////////////////////////////////
376
377 // Generate enough trade information to put into
378 // the priority queue.
379 //
380 void GenerateNewTrade();
381
382 // Take the incoplete trade information and
383 // generate all the trade-related rows in internal
384 // row structures.
385 //
386 void GenerateCompleteTrade();
387
388 // Generate a random delay (in seconds) between
389 // two consecutive trades.
390 //
391 inline double GenerateDelayBetweenTrades();
392
393 // Return the list of holdings to modify
394 // by the most recently generated complete trade
395 //
396 inline THoldingList *GetHoldingListForCurrentTrade();
397
398 // Return position before the first or the last element
399 // in the holding list (depending on IsLifo flag)
400 //
401 list<THoldingInfo>::iterator PositionAtHoldingList(THoldingList *pHoldingList, int IsLifo);
402 // Update holding information for the customer and trade
403 // contained in the internal trade row structure.
404 // Set internal buy and sell values.
405 //
406 void UpdateHoldings();
407
408 // Position internal iterator at the next non-empty holding.
409 // Update internal customer/account/security counters as required.
410 //
411 // Return whether a non-empty holding exists.
412 //
413 bool FindNextHolding();
414
415 // Position internal indexes to next non-empty list of holdings
416 // Return whether non-empty holding list exists.
417 //
418 bool FindNextHoldingList();
419
420 // Generate a new trade id
421 //
422 TTrade GenerateNextTradeId();
423
424 // Generate a random trade type
425 //
426 eTradeTypeID GenerateTradeType();
427
428 // Generate some common fields for the completed trade.
429 // Those fields are used more than once so they are stored
430 // in a separate structure.
431 //
432 void GenerateCompletedTradeInfo();
433
434 // Generate TRADE row
435 //
436 void GenerateTradeRow();
437
438 void GenerateTradeCharge();
439
440 void GenerateTradeCommission();
441
442 void GenerateTradeTax();
443
444 // Generate settlement amount for SE_AMT and CT_AMT
445 //
446 void GenerateSettlementAmount();
447
448 // Generate TRADE_HISTORY rows
449 //
450 void GenerateTradeHistoryRow();
451
452 // Generate CASH_TRANSACTION row
453 //
454 void GenerateCashTransactionRow();
455
456 // Generate SETTLEMENT row
457 //
458 void GenerateSettlementRow();
459
460 // Generate HOLDING_HISTORY row
461 //
462 void GenerateHoldingHistoryRow(TTrade iHoldingTradeID, // trade id of the original trade
463 TTrade iTradeTradeID, // trade id of the modifying trade
464 int iBeforeQty, // holding qty now
465 int iAfterQty); // holding qty after modification
466
467 // Helper function to get the current customer id
468 TIdent GetCurrentCustID() {
469 return m_NewTrade.iCustomer;
470 }
471 // Helper function to get the current customer tier
472 int GetCurrentCustTier() {
473 return m_NewTrade.iCustomerTier;
474 }
475 // Helper function to get the current account id
476 TIdent GetCurrentAccID() {
477 return m_NewTrade.iCustomerAccount;
478 }
479 // Helper function to get the current trade id
480 TTrade GetCurrentTradeID() {
481 return m_NewTrade.iTradeId;
482 }
483 // Helper function to get the current trade bid price
484 CMoney GetCurrentBidPrice() {
485 return m_NewTrade.fBidPrice;
486 }
487 // Helper function to get the current trade execution price
488 CMoney GetCurrentTradePrice() {
489 return m_NewTrade.fTradePrice;
490 }
491 // Helper function to get the current trade quantity
492 int GetCurrentTradeQty() {
493 return m_NewTrade.iTradeQty;
494 }
495 // Helper function to get the current trade type
496 eTradeTypeID GetCurrentTradeType() {
497 return m_NewTrade.eTradeType;
498 }
499 // Helper function to get the current trade status
500 eStatusTypeID GetCurrentTradeStatus() {
501 return m_NewTrade.eTradeStatus;
502 }
503 // Helper function to get whether the current trade is cash
504 int GetCurrentTradeIsCash() {
505 return m_TradeRow.m_Trade.T_IS_CASH;
506 }
507 // Helper function to get the current security symbol index
508 TIdent GetCurrentSecurityIndex() {
509 return m_NewTrade.iSymbolIndex;
510 }
511 // Helper function to get the current security index in the account's basket
512 // (1-25)
513 UINT GetCurrentSecurityAccountIndex() {
514 return m_NewTrade.iSymbolIndexInAccount;
515 }
516 // Helper function to get the current trade pending time
517 CDateTime GetCurrentTradePendingTime() {
518 CDateTime ReturnTime = m_StartTime;
519 int iDays, iMs;
520
521 // submit days separately to avoid int32 overflow in ms after 25 days
522
523 iDays = (int)(m_NewTrade.PendingTime / SecondsPerDay);
524 iMs = (int)((m_NewTrade.PendingTime - iDays * SecondsPerDay) * MsPerSecond);
525 ReturnTime.Add(iDays, iMs,
526 true); // add days and msec and adjust for weekend
527
528 return ReturnTime;
529 }
530 // Helper function to get the current trade submission time
531 CDateTime GetCurrentTradeSubmissionTime() {
532 CDateTime ReturnTime = m_StartTime;
533 int iDays, iMs;
534
535 // submit days separately to avoid int32 overflow in ms after 25 days
536
537 iDays = (int)(m_NewTrade.SubmissionTime / SecondsPerDay);
538 iMs = (int)((m_NewTrade.SubmissionTime - iDays * SecondsPerDay) * MsPerSecond);
539 ReturnTime.Add(iDays, iMs,
540 true); // add days and msec and adjust for weekend
541
542 return ReturnTime;
543 }
544 // Helper function to get the current trade completion time
545 CDateTime GetCurrentTradeCompletionTime() {
546 CDateTime ReturnTime = m_StartTime;
547
548 int iDays, iMs;
549
550 // submit days separately to avoid int32 overflow in ms after 25 days
551
552 iDays = (int)(m_NewTrade.CompletionTime / SecondsPerDay);
553 iMs = (int)((m_NewTrade.CompletionTime - iDays * SecondsPerDay) * MsPerSecond);
554 ReturnTime.Add(iDays, iMs,
555 true); // add days and msec and adjust for weekend
556
557 return ReturnTime;
558 }
559 // Helper function to get the current trade's is_lifo flag
560 bool GetCurrentTradeIsLifo() {
561 return m_NewTrade.bIsLifo;
562 }
563 // Helper function to get the current trade's sell value
564 CMoney GetCurrentTradeSellValue() {
565 return m_CompletedTradeInfo.fSellValue;
566 }
567 // Helper function to get the current trade's buy value
568 CMoney GetCurrentTradeBuyValue() {
569 return m_CompletedTradeInfo.fBuyValue;
570 }
571 // Helper function to get the current account broker id
572 TIdent GetCurrentBrokerId() {
573 return m_CompletedTradeInfo.iCurrentBrokerId;
574 }
575 // Helper function to get the current account tax status
576 eTaxStatus GetCurrentTaxStatus() {
577 return m_CompletedTradeInfo.eAccountTaxStatus;
578 }
579 // Helper function to get the current trade's charge amount
580 CMoney GetCurrentTradeCharge() {
581 return m_CompletedTradeInfo.Charge;
582 }
583 // Helper function to get the current trade's commission amount
584 CMoney GetCurrentTradeCommission() {
585 return m_CompletedTradeInfo.Commission;
586 }
587 // Helper function to get the current trade's tax amount
588 CMoney GetCurrentTradeTax() {
589 return m_CompletedTradeInfo.Tax;
590 }
591 // Helper function to get the current trade's settlement amount
592 CMoney GetCurrentSettlementAmount() {
593 return m_CompletedTradeInfo.SettlementAmount;
594 }
595
596public:
597 // Constructor
598 //
599 CTradeGen(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer, TIdent iTotalCustomers,
600 UINT iLoadUnitSize, UINT iScaleFactor, UINT iHoursOfInitialTrades, bool bCacheEnabled = false);
601
602 // Destructor
603 //
604 ~CTradeGen();
605
606 // Generate one Trade Result and return the
607 // resulting trade. This function will generate
608 // a new incomplete trade (Trade Order) if needed
609 // and put it onto the priority queue.
610 // It will also update the holding information
611 // as needed.
612 //
613 // Returns whether there is another trade to return.
614 //
615 bool GenerateNextTrade();
616
617 // Generate next HOLDING_SUMMARY record.
618 // Returns whether there is another HOLDING_SUMMARY record to return.
619 //
620 bool GenerateNextHoldingSummaryRow();
621
622 // Generate next holding row.
623 // This function will check internal state and
624 // throw an exception if not all trades
625 // have been generated.
626 //
627 // Returns whether there is another HOLDING row to return.
628 //
629 bool GenerateNextHolding();
630
631 // Initialize next load unit and prepare it for
632 // GenerateNextTrade/GenerateNextHolding calls.
633 // The first load unit doesn't have to be initialized.
634 //
635 // Return whether the next load unit exists
636 //
637 bool InitNextLoadUnit();
638
639 // Accessors for internal row structures.
640 //
641 const TRADE_ROW &GetTradeRow() {
642 return m_TradeRow.m_Trade;
643 }
644 int GetTradeHistoryRowCount() {
645 return m_iTradeHistoryRowCount;
646 }
647 const TRADE_HISTORY_ROW &GetTradeHistoryRow(int i) {
648 return m_TradeRow.m_TradeHistory[i];
649 }
650 int GetSettlementRowCount() {
651 return m_iSettlementRowCount;
652 }
653 const SETTLEMENT_ROW &GetSettlementRow() {
654 return m_TradeRow.m_Settlement;
655 }
656 int GetCashTransactionRowCount() {
657 return m_iCashTransactionRowCount;
658 }
659 const CASH_TRANSACTION_ROW &GetCashTransactionRow() {
660 return m_TradeRow.m_CashTransaction;
661 }
662 const HOLDING_ROW &GetHoldingRow() {
663 return m_HoldingRow;
664 }
665 int GetHoldingHistoryRowCount() {
666 return m_iHoldingHistoryRowCount;
667 }
668 const HOLDING_HISTORY_ROW &GetHoldingHistoryRow(int i) {
669 return m_TradeRow.m_HoldingHistory[i];
670 }
671 const HOLDING_SUMMARY_ROW &GetHoldingSummaryRow() {
672 return m_HoldingSummaryRow;
673 }
674
675 bool GenerateNextBrokerRecord() {
676 return m_BrokerTable.GenerateNextRecord();
677 }
678 const BROKER_ROW &GetBrokerRow() {
679 return m_BrokerTable.GetRow();
680 }
681};
682
683} // namespace TPCE
684
685#endif // TRADE_GEN_H
686