// ***************************************************************** // **** 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()
}// GetRequest() // // // // ********************************************************* // **** ProcessFoundResources() **** // ********************************************************* /// <summary> /// Called by the hub thread to deal with newly found resources from the market. /// This is where we request subscription to price feeds we need. /// </summary> /// <param name="arg"></param> private void ProcessFoundResources(FoundServiceEventArg arg) { if (arg.FoundProducts != null) { foreach (Product product in arg.FoundProducts) { if (m_ProductsRequested.Contains(product)) // this is a product we want to record! { m_Market.RequestInstruments(product); // asynchronous call to find out all instruments for this product. } } // end product } else if (arg.FoundInstruments != null) { // we should now have save instrument details in the market dictionary List <Product> productsToProcess = new List <Product>(); // keep a list of any products we need to process for subscription. foreach (InstrumentName instrName in arg.FoundInstruments) // check if we want to know about this product { // find all the products we care about in these instruments if (m_ProductsRequested.Contains(instrName.Product)) { // we have requested this product! if (m_InstrumentsByProduct.ContainsKey(instrName.Product)) { // we already have this product if (!m_InstrumentsByProduct[instrName.Product].Contains(instrName)) { // the instrument isn't in our list however m_InstrumentsByProduct[instrName.Product].Add(instrName); if (!productsToProcess.Contains(instrName.Product)) { // make sure we add this product to the list to possibly subscribe to below. productsToProcess.Add(instrName.Product); } } } else {// the product doesn't exist yet in our list. List <InstrumentName> instrListToAdd = new List <InstrumentName>(); instrListToAdd.Add(instrName); m_InstrumentsByProduct.Add(instrName.Product, instrListToAdd); productsToProcess.Add(instrName.Product); // add to our list to process! } } } // end foreach // // tell the market to subscribe here // Log.NewEntry(LogLevel.Major, "DataHub: Found new instruments in {0} products", productsToProcess.Count); foreach (Product product in productsToProcess) { Log.NewEntry(LogLevel.Major, "DataHub: Processing found instruments for {0}", product.ProductName); List <InstrumentName> instrumentsInProduct = new List <InstrumentName>(); // create list of instruments m_InstrumentsByProduct.TryGetValue(product, out instrumentsInProduct); // try and get all the instruments for this product List <InstrumentDetails> instrDetailList = new List <InstrumentDetails>(); // create list on details for these instruments List <InstrumentDetails> filteredInstrumentDetailList = new List <InstrumentDetails>(); // filtered list of instruments. if (m_Market.TryGetInstrumentDetails(instrumentsInProduct, out instrDetailList)) { // we have instrument details to look at instrDetailList.Sort((x, y) => x.ExpirationDate.CompareTo(y.ExpirationDate)); // sort list by expirations... int noOfContracts = 0; foreach (ProductRequest prodRequest in m_ProductRequestList) { if (prodRequest.Product.Equals(product)) { // we found a request for this prod if (prodRequest.nInstrumentsToRecord > noOfContracts) // we need to request more contracts { noOfContracts = prodRequest.nInstrumentsToRecord; // set the number of contracts } if (prodRequest.m_IsStandardInstrumentsOnly) {// we need to filter! foreach (InstrumentDetails instrDetails in instrDetailList) { if (instrDetails.isStandard) { filteredInstrumentDetailList.Add(instrDetails); // add all "standard" contracts } } } else { // we don't need to filter, so just assign to use all instrumnets we found. filteredInstrumentDetailList = instrDetailList; } } } // end prodRequest noOfContracts = Math.Min(noOfContracts, filteredInstrumentDetailList.Count); // if we are trying to subscribe to more contracts than exist! for (int i = 0; i < noOfContracts; i++) { int mySQLID = -1; // // the following query building should really be pushed on to the querybuilder hub, since it is set up related, and only happens // once I am leaving it here. this should be changed eventually. // if (m_InstrToMySQLID.ContainsKey(filteredInstrumentDetailList[i].InstrumentName)) // quick check to make sure we have never dealt with this instrument. { continue; } if (DBInstrument.TryGetMySQLInstrumentId(m_DataBaseInfo, filteredInstrumentDetailList[i].InstrumentName, out mySQLID)) { // we have it now and should save it in both look up tables. m_InstrToMySQLID.Add(filteredInstrumentDetailList[i].InstrumentName, mySQLID); // create mapping between instrument and ID. m_MySQLIDToInstr.Add(mySQLID, filteredInstrumentDetailList[i].InstrumentName); // backwards mapping just in case. string instrDetailsToWriteToDB; if (DBInstrument.TryCheckMySQLInstrumentDetails(m_DataBaseInfo, // make sure our data matches in the db is correct filteredInstrumentDetailList[i], out instrDetailsToWriteToDB)) { // we succesffuly checked our instr details. if (instrDetailsToWriteToDB != string.Empty) { // if our string isn't empty we need to write data m_DatabaseWriterHub.ExecuteNonQuery(instrDetailsToWriteToDB); // send it to the db writer hub Log.NewEntry(LogLevel.Minor, "ProcessFoundResources is ammending instruments details for {0} to the database", filteredInstrumentDetailList[i].InstrumentName); } } m_Market.RequestInstrumentPriceSubscription(filteredInstrumentDetailList[i].InstrumentName); // subscribe to instrument m_Market.RequestInstrumentTimeAndSalesSubscription(filteredInstrumentDetailList[i].InstrumentName); // request time and sales m_InstrumentsRequested.Add(filteredInstrumentDetailList[i].InstrumentName); // add it to our list of subscriptions. } else { Log.NewEntry(LogLevel.Error, "ProcessFoundResources cannot find {0} in database - removing from list", filteredInstrumentDetailList[i].InstrumentName); } } // end i } } // end entry (foreach) } else { Log.NewEntry(LogLevel.Error, "DataHub.ProcessFoundResources empty event type recvd {0}", arg.ToString()); } }