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 representing the DAILY_MARKET table.
40 */
41#ifndef DAILY_MARKET_TABLE_H
42#define DAILY_MARKET_TABLE_H
43
44#include "EGenTables_common.h"
45#include "SecurityPriceRange.h"
46
47#include "input/DataFileManager.h"
48
49namespace TPCE {
50
51const int iTradeDaysInYear = 261; // the number of trading days in a year (for DAILY_MARKET)
52const int iDailyMarketYears = 5; // number of years of history in DAILY_MARKET
53const int iDailyMarketTotalRows = iDailyMarketYears * iTradeDaysInYear;
54
55const double fDailyMarketCloseMin = fMinSecPrice;
56const double fDailyMarketCloseMax = fMaxSecPrice;
57
58const double fDailyMarketHighRelativeToClose = 1.05;
59const double fDailyMarketLowRelativeToClose = 0.92;
60
61const INT64 iDailyMarketVolumeMax = 10000;
62const INT64 iDailyMarketVolumeMin = 1000;
63
64const int iRNGSkipOneRowDailyMarket = 2; // number of RNG calls for one row
65
66typedef struct DAILY_MARKET_GEN_ROW {
67 // big array of all the history for one security
68 DAILY_MARKET_ROW m_daily_market[iDailyMarketTotalRows];
69} * PDAILY_MARKET_GEN_ROW;
70
71class CDailyMarketTable : public TableTemplate<DAILY_MARKET_GEN_ROW> {
72 TIdent m_iStartFromSecurity;
73 TIdent m_iSecurityCount;
74 const CSecurityFile &m_SecurityFile;
75 CDateTime m_StartFromDate;
76 int m_iDailyMarketTotalRows;
77 // Number of times GenerateNextRecord() was called for the current security
78 // data. Needed to decide when to generate next security's data.
79 int m_iRowsGeneratedPerSecurity;
80 // Stores whether there is another security(s) for which to
81 // generate daily market data.
82 bool m_bMoreSecurities;
83 TIdent m_iSecurityCountForOneLoadUnit;
84
85 /*
86 * DAILY_MARKET table rows generation
87 */
88 void GenerateDailyMarketRows() {
89 int i;
90 int iDayNo = 0; // start from the oldest date (start date)
91 char szSymbol[cSYMBOL_len + 1];
92
93 // Create symbol only once.
94 //
95 m_SecurityFile.CreateSymbol(m_iLastRowNumber, szSymbol, static_cast<int>(sizeof(szSymbol)));
96
97 for (i = 0; i < m_iDailyMarketTotalRows; ++i) {
98 // copy the symbol
99 strncpy(m_row.m_daily_market[i].DM_S_SYMB, szSymbol, sizeof(m_row.m_daily_market[i].DM_S_SYMB));
100
101 // generate trade date
102 m_row.m_daily_market[i].DM_DATE = m_StartFromDate;
103 m_row.m_daily_market[i].DM_DATE.Add(iDayNo, 0);
104
105 // generate prices
106 m_row.m_daily_market[i].DM_CLOSE =
107 m_rnd.RndDoubleIncrRange(fDailyMarketCloseMin, fDailyMarketCloseMax, 0.01);
108 m_row.m_daily_market[i].DM_HIGH = m_row.m_daily_market[i].DM_CLOSE * fDailyMarketHighRelativeToClose;
109 m_row.m_daily_market[i].DM_LOW = m_row.m_daily_market[i].DM_CLOSE * fDailyMarketLowRelativeToClose;
110
111 // generate volume
112 m_row.m_daily_market[i].DM_VOL = m_rnd.RndInt64Range(iDailyMarketVolumeMin, iDailyMarketVolumeMax);
113
114 ++iDayNo; // go one day forward for the next row
115
116 if ((iDayNo % DaysPerWeek) == DaysPerWorkWeek)
117 iDayNo += 2; // skip weekend
118 }
119 }
120
121 /*
122 * Reset the state for the next load unit.
123 *
124 * PARAMETERS:
125 * none.
126 *
127 * RETURNS:
128 * none.
129 */
130 void InitNextLoadUnit() {
131 m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedTableDefault, (RNGSEED)m_iLastRowNumber * iRNGSkipOneRowDailyMarket));
132
133 ClearRecord(); // this is needed for EGenTest to work
134 }
135
136public:
137 /*
138 * Constructor.
139 */
140 CDailyMarketTable(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer)
141 : TableTemplate<DAILY_MARKET_GEN_ROW>(), m_SecurityFile(dfm.SecurityFile()),
142 m_iDailyMarketTotalRows(sizeof(m_row.m_daily_market) / sizeof(m_row.m_daily_market[0])),
143 m_iRowsGeneratedPerSecurity(sizeof(m_row.m_daily_market) / sizeof(m_row.m_daily_market[0])),
144 m_bMoreSecurities(true) // initialize once
145 {
146 // Set DAILY_MARKET start date to Jan 03, 2000.
147 //
148 m_StartFromDate.Set(iDailyMarketBaseYear, iDailyMarketBaseMonth, iDailyMarketBaseDay, iDailyMarketBaseHour,
149 iDailyMarketBaseMinute, iDailyMarketBaseSecond, iDailyMarketBaseMsec);
150
151 m_bMoreRecords = true; // initialize once
152
153 m_iSecurityCount = m_SecurityFile.CalculateSecurityCount(iCustomerCount);
154 m_iStartFromSecurity = m_SecurityFile.CalculateStartFromSecurity(iStartFromCustomer);
155
156 m_iSecurityCountForOneLoadUnit = m_SecurityFile.CalculateSecurityCount(iDefaultLoadUnitSize);
157
158 m_iLastRowNumber = m_iStartFromSecurity;
159 };
160
161 bool GenerateNextRecord() {
162 ++m_iRowsGeneratedPerSecurity;
163
164 if (m_iRowsGeneratedPerSecurity >= m_iDailyMarketTotalRows) {
165 if (m_bMoreSecurities) {
166 // Reset RNG at Load Unit boundary, so that all data is
167 // repeatable.
168 //
169 if (m_iLastRowNumber % m_iSecurityCountForOneLoadUnit == 0) {
170 InitNextLoadUnit();
171 }
172
173 GenerateDailyMarketRows(); // generate all rows for the current
174 // security
175
176 ++m_iLastRowNumber;
177
178 // Update state info
179 m_bMoreSecurities = m_iLastRowNumber < (m_iStartFromSecurity + m_iSecurityCount);
180
181 m_iRowsGeneratedPerSecurity = 0;
182 }
183 }
184
185 // Return false when generated the last row of the last security
186 if (!m_bMoreSecurities && (m_iRowsGeneratedPerSecurity == m_iDailyMarketTotalRows - 1)) {
187 m_bMoreRecords = false;
188 }
189
190 return (MoreRecords());
191 }
192
193 const DAILY_MARKET_ROW &GetRow() {
194 return m_row.m_daily_market[m_iRowsGeneratedPerSecurity];
195 }
196};
197
198} // namespace TPCE
199
200#endif // DAILY_MARKET_TABLE_H
201