// // // // // // ********************************************************* // **** 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().
}//end HubEvent // // // // #endregion// Hub Event Handler overrides #region Public Methods // ***************************************************************** // **** Public Methods **** // ***************************************************************** // // //*********************************************** // **** Start() **** //*********************************************** public override void Start() { // // Create needed hubs // m_DatabaseWriterHub = new DatabaseWriterHub(m_DataBaseInfo); m_DatabaseWriterHub.Log.AllowedMessages = LogLevel.ShowAllMessages; m_DatabaseWriterHub.Log.IsViewActive = true; m_DatabaseWriterHub.WriteCompleted += new EventHandler(this.HubEventEnqueue); m_DatabaseWriterHub.Start(); m_QueryBuilderHub = new QueryBuilderHub(this, m_DatabaseWriterHub); // // Set datetime bars. // DateTime dt = Log.GetTime(); double totalSeconds = dt.Minute * 60.0 + dt.Second; dt = dt.AddSeconds(-totalSeconds); // rip off minutes and seconds. totalSeconds = Math.Ceiling(totalSeconds / m_BarTimeStep) * m_BarTimeStep; // rounding off to nearest bar. totalSeconds += m_BarTimeStep; // increment to next bar. dt = dt.AddSeconds(totalSeconds); // set bar time. dt = dt.AddMilliseconds(-dt.Millisecond); m_NextBar = dt; base.m_WaitListenUpdatePeriod = 100; // update every n ms // // Find stop time. // DateTime today = DateTime.Today; DateTime startTime = DateTime.Now; m_EndRecordingDateTime = today.AddMinutes(60 * 16 + 20); // we want to stop each day at 4:20 pm if (m_StopFrequency == StopFrequency.Daily) { if (startTime > m_EndRecordingDateTime) // it is already past 4:20, so stop the next day at 4:20 { m_EndRecordingDateTime = m_EndRecordingDateTime.AddDays(1); } } else if (m_StopFrequency == StopFrequency.Weekly) { int daysToAdd = ((int)DayOfWeek.Friday - (int)startTime.DayOfWeek + 7) % 7; m_EndRecordingDateTime = m_EndRecordingDateTime.AddDays(daysToAdd); } Log.NewEntry(LogLevel.Major, "DataHub: Scheduled Shutdown for {0} ", m_EndRecordingDateTime); // List <ProductRequest> startingRequestList; ProductRequest.TryCreateFromFile("ProductRequest.txt", out startingRequestList); // // Split requests into smaller subsets to avoid TT Choking. // if (startingRequestList.Count > m_MaxProductsPerRequest) { // we need to subset. int reqCount = 0; //dummy counter varialble while (reqCount < startingRequestList.Count) { // iterate through and subset lists until we are completed. List <ProductRequest> subsettedList = new List <ProductRequest>(); int endOfList = Math.Min(m_MaxProductsPerRequest, startingRequestList.Count - reqCount); //this ensures we don't mess up the indexing subsettedList = startingRequestList.GetRange(reqCount, endOfList); m_SplitProdReqs.Add(subsettedList); reqCount += m_MaxProductsPerRequest; } } else { m_SplitProdReqs.Add(startingRequestList); // no need to subset, just add them all. } m_nProductRequested = startingRequestList.Count; // store for reporting purposes // // Send email's on startup // if (m_IsEmailOnStartStop) { // we can abuse the DataBaseWrtiter to send start and stop emails DatabaseWriterEventArgs emailEvent = new DatabaseWriterEventArgs(); emailEvent.Request = DatabaseWriterRequests.SendEmail; emailEvent.QueryBase.AppendFormat("Data Hub Starting {0}", DateTime.Now); emailEvent.QueryValues.AppendFormat("Data Hub requesting {0} products to be recorded to {1}. Scheduled for shutdown at {2}", m_nProductRequested, m_DataBaseInfo.Location, m_EndRecordingDateTime); m_DatabaseWriterHub.HubEventEnqueue(emailEvent); } base.Start(); m_IsReadyToRequest = true; }// Start()