// ***************************************************************** // **** Private Methods **** // ***************************************************************** // /// <summary> /// Creates the queury /// </summary> private void ProcessQueryBuildEvent() { Log.NewEntry(LogLevel.Minor, "ProcessQueryBuildEvent: Processing {0} rows.", m_EventList.Count.ToString()); while (m_EventList.Count > 0) // while there are events to process... { m_Body.Remove(0, m_Body.Length); // clear entire content of last command m_Header.Remove(0, m_Header.Length); int rowCount = 0; // Process all events that share *same* header. (Same table name). string tableName = string.Empty; // we will check that this is empty, signals new write query. while (m_EventList.Count > 0) { // Peek at next event to process. We will write as many as we can that share a common // header. (That is, common table name.) BarEventArgs barArg = m_EventList.Peek(); // this contains many instruments, but with one common timestamp! string tbName = m_DatabaseInfo.Bars.TableNameFull; if (string.IsNullOrEmpty(tableName)) { // First time we came thru here, or we just breaked out from last tableName = tbName; m_Header.AppendFormat(Bar.QueryHeader, tableName); } else if (!tableName.Equals(tbName)) { break; // we must not add these bars to current query. } // // Write the queries for this event // barArg = m_EventList.Dequeue(); // dequeue the barEventArg we will NOW process! string timeStamp = barArg.unixTime.ToString(); // create unix time stamp while (barArg.BarList.Count > 0) // load all bars in this event. { Bar abar = barArg.BarList.Dequeue(); // extract bars from the eventArg! if (rowCount == 0) // first value for this query. { m_Body.Append("("); } else { m_Body.Append(",("); } m_Body.Append(abar.GetQueryValues(timeStamp)); // add values for entire instr. bar. m_Body.Append(")"); m_DataHub.m_BarFactory.Recycle(abar); // we are done with the bar now, recycle rowCount++; // each set of values will lead to a new row. } m_DataHub.m_BarEventFactory.Recycle(barArg); // done with this event, recycle it }//while m_Body.Append(";"); // finish query construction. m_DatabaseWriter.ExecuteNonQuery(string.Format("{0} {1}", m_Header.ToString(), m_Body.ToString())); }//while events to process. }// ProcessQueryBuildEvent()
// // // // // // ********************************************************* // **** CreateBar() **** // ********************************************************* /// <summary> /// This is called each time a bar must be created from a snapshot of the current market. /// New bars are pushed into the BarEventArg.BarList queue and handed to the QueryBuilder /// for query creation and writing. /// Called by internal hub thread. /// </summary> private void CreateBar(DateTime barTime) { //Log.NewEntry(LogLevel.Minor, "DataHub: CreateBar - Bar Creation Started"); BarEventArgs eArg = m_BarEventFactory.Get(); // new version GetBarEventArg(); eArg.unixTime = (int)Utilities.QTMath.DateTimeToEpoch(barTime.ToUniversalTime()); //round this to the floor. Log.NewEntry(LogLevel.Minor, "CreateBar: Attempting to create bar for timestamp {0} - miliseconds = {1}", eArg.unixTime, barTime.Millisecond); if ((eArg.unixTime - m_LastBarTimeStamp) > 1) { // we have stepped through time in some interval greater than a second....create email alert for debugging purposes DatabaseWriterEventArgs emailEvent = new DatabaseWriterEventArgs(); emailEvent.Request = DatabaseWriterRequests.SendEmail; emailEvent.QueryBase.AppendFormat("Data Hub Missed Timestamp. Current timestamp={0} and last timestamp={1} difference is {2} seconds", eArg.unixTime, m_LastBarTimeStamp, eArg.unixTime - m_LastBarTimeStamp); m_DatabaseWriterHub.HubEventEnqueue(emailEvent); } m_LastBarTimeStamp = eArg.unixTime; // // Get markets now. // UV.Lib.BookHubs.Book aBook; if (m_Market.TryEnterReadBook(out aBook)) { foreach (KeyValuePair <int, UV.Lib.BookHubs.Market> aBookMarket in aBook.Instruments) { int mySQLID = -1; if (m_InstrumentsRequested.Contains(aBookMarket.Value.Name) && m_InstrToMySQLID.TryGetValue(aBookMarket.Value.Name, out mySQLID)) { // we would like to record data for this instrument if (aBookMarket.Value.Qty[(int)UV.Lib.Utilities.QTMath.BidSide][0] == 0 || aBookMarket.Value.Qty[(int)UV.Lib.Utilities.QTMath.AskSide][0] == 0) {// we have bad data this can happen sometimes in between sessions.. //Log.NewEntry(LogLevel.Major, "CreateBar: Bid Or Ask qty for {0} is equal To zero, skipping bar", aBookMarket.Value.Name); continue; } Bar aBar = m_BarFactory.Get(); // grab a bar! aBar.mysqlID = mySQLID; // set instrument id aBar.bidPrice = aBookMarket.Value.Price[(int)UV.Lib.Utilities.QTMath.BidSide][0]; // set best bid aBar.askPrice = aBookMarket.Value.Price[(int)UV.Lib.Utilities.QTMath.AskSide][0]; // set best ask aBar.bidQty = aBookMarket.Value.Qty[(int)UV.Lib.Utilities.QTMath.BidSide][0]; // set best bidqty aBar.askQty = aBookMarket.Value.Qty[(int)UV.Lib.Utilities.QTMath.AskSide][0]; // set best askqty aBar.lastTradePrice = aBookMarket.Value.LastPrice; aBar.sessionVolume = aBookMarket.Value.Volume[(int)UV.Lib.Utilities.QTMath.LastSide]; aBar.longVolume = aBookMarket.Value.Volume[(int)UV.Lib.Utilities.QTMath.BidSide]; aBar.shortVolume = aBookMarket.Value.Volume[(int)UV.Lib.Utilities.QTMath.AskSide]; aBar.totalVolume = aBar.longVolume + aBar.shortVolume + aBookMarket.Value.Volume[(int)UV.Lib.Utilities.QTMath.UnknownSide]; aBar.sessionCode = Convert.ToInt32(aBookMarket.Value.IsMarketGood); // flag for trading ==1 or not trading==0 eArg.BarList.Enqueue(aBar); } } m_Market.ExitReadBook(aBook); } else { // something went wrong here! Log.NewEntry(LogLevel.Error, " ********* CreateBar: FAILED TO OBTAIN READ FOR BOOK! *********"); } if (eArg.BarList.Count > 0 && !m_IsDebugMode) // do not write to db in debug mode. { m_QueryBuilderHub.HubEventEnqueue(eArg); } }//CreateBar().