| 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 |  | 
|---|
| 67 | using namespace std; | 
|---|
| 68 |  | 
|---|
| 69 | namespace 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 | // | 
|---|
| 78 | const int iMaxHoldingHistoryRowsPerTrade = 800 / 100; | 
|---|
| 79 |  | 
|---|
| 80 | // Incomplete trade information generated | 
|---|
| 81 | // at Trade Order time. | 
|---|
| 82 | // | 
|---|
| 83 | typedef 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 | 
|---|
| 103 | typedef 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 | // | 
|---|
| 131 | typedef 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 | // | 
|---|
| 144 | typedef 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 | // | 
|---|
| 155 | typedef list<THoldingInfo> THoldingList; | 
|---|
| 156 | typedef THoldingList TCustomerHoldingArray[iMaxSecuritiesPerAccount]; | 
|---|
| 157 |  | 
|---|
| 158 | class 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 |  | 
|---|
| 596 | public: | 
|---|
| 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 |  | 
|---|