예제 #1
0
        }     // ProcessRequest()

        //
        //
        // *************************************************
        // ****             Process Query()           ****
        // *************************************************
        private void ProcessQuery(EventArgs eventArgs)
        {
            Type type = eventArgs.GetType();

            if (type == typeof(DB.Queries.ExchangeInfoQuery))
            {
                m_ExchInfo = (DB.Queries.ExchangeInfoQuery)eventArgs;   // Just store this info for later.
            }
            else if (type == typeof(DB.Queries.ProductInfoQuery))
            {
                m_ProductInfo = (DB.Queries.ProductInfoQuery)eventArgs; // just store this info for later.
            }
            else if (type == typeof(DB.Queries.InstrumentInfoQuery))
            {                                                           // Extract instr details from this result.
                DB.Queries.InstrumentInfoQuery query = (DB.Queries.InstrumentInfoQuery)eventArgs;

                if (query.Status == DB.Queries.QueryStatus.Failed)
                {
                    Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to find instrument {0} in database.", query.InstrumentName);
                }
                else if (query.Results == null || query.Results.Count == 0)
                {
                    Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to create details for {0} from database.", query.InstrumentName);
                }
                else
                {                                                          // Extract details from the query results
                    DB.Queries.InstrumentInfoItem item = query.Results[0]; // I ask for instruments one at a time.
                    InstrumentDetails             details;
                    if (item.TryGetInstrumentDetails(query.InstrumentName, out details))
                    {
                        if (TryAddInstrumentDetails(query.InstrumentName, details))
                        {
                            Log.NewEntry(LogLevel.Minor, "ProcessQuery: Added instr details for {0}.", query.InstrumentName);
                            List <InstrumentName> instrNamesFound = new List <InstrumentName>();
                            instrNamesFound.Add(query.InstrumentName);
                            base.OnInstrumentFound(instrNamesFound);
                            m_IsResubmitPendingRequests = true;
                        }
                        else
                        {
                            Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to add instr details for {0}.", query.InstrumentName);
                        }
                    }
                    else
                    {
                        Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to create instr details for {0}.", query.InstrumentName);
                    }
                }
                // Mark this query as completed.
                if (m_PendingInstrumentQueries.Contains(query.InstrumentName))
                {
                    m_PendingInstrumentQueries.Remove(query.InstrumentName);    // remove the query, it's finished.
                }
            }
            else if (type == typeof(DB.Queries.MarketDataQuery))
            {
                DB.Queries.MarketDataQuery query = (DB.Queries.MarketDataQuery)eventArgs;
                int id;
                if (m_PendingMarketDataQueries.Contains(query))
                {
                    m_PendingMarketDataQueries.Remove(query);
                    if (query.Status == DB.Queries.QueryStatus.Failed)
                    {
                        Log.NewEntry(LogLevel.Warning, "ProcessQuery: Failed to find instrument {0} in database.", query.InstrumentName);
                    }
                    else if (TryLookupInstrumentID(query.InstrumentName, out id))
                    {   // Books for this instrument already exist.
                        // In future, this occurs when we ask for mode data for pre-existing instrument.
                        Log.NewEntry(LogLevel.Warning, "ProcessQuery: Query {1} for existing market {0}.", query.InstrumentName, query.QueryID);
                    }
                    else
                    {     // No book yet exists for this instrument.
                        if (TryCreateNewBook(query.InstrumentName))
                        { // New book created.
                            Log.NewEntry(LogLevel.Major, "ProcessQuery: Created book for instrument {0}.", query.InstrumentName);
                            if (TryLookupInstrumentID(query.InstrumentName, out id))
                            {
                                if (query.Result == null || query.Result.Count < 10)
                                {
                                    Log.NewEntry(LogLevel.Warning, "ProcessQuery: Have no market data for instrument {0}.", query.InstrumentName);
                                }
                                // Create the MarketDataItem holder
                                m_MarketItems.Add(id, new List <DB.Queries.MarketDataItem>(query.Result));
                                m_MarketItemPtrs.Add(id, 0);                // set starting position to zero.
                                // If this is first instrument data call back, initial the sim variables.
                                if (!m_IsSimInitialized && m_MarketItems[id].Count > 0)
                                {
                                    m_UtcNow = m_MarketItems[id][0].UnixTime;
                                    DateTime dt = this.LocalTime;   // test
                                    m_IsSimInitialized = true;
                                }
                            }
                            // Fire book created event.
                            List <InstrumentName> booksCreated = new List <InstrumentName>();
                            booksCreated.Add(query.InstrumentName);
                            OnMarketBookCreated(booksCreated);
                        }
                        else
                        {
                            Log.NewEntry(LogLevel.Major, "ProcessQuery: Failed to create new book for {0}.", query.InstrumentName);
                        }
                    }
                }
            }

            //
            // Test for readiness
            //
            if (m_IsDatabaseInitialized == false && m_ExchInfo != null && m_ProductInfo != null)
            {
                m_IsDatabaseInitialized = true;
                Log.NewEntry(LogLevel.Minor, "ProcessQuery: Loading database tables complete. Submitting {0} pending requests.", m_PendingRequests.Count);
                while (m_PendingRequests.Count > 0)
                {
                    RequestEventArg <RequestCode> request = m_PendingRequests[0];
                    m_PendingRequests.RemoveAt(0);
                    this.HubEventEnqueue(request);
                }
            }
        }// ProcessQuery
예제 #2
0
        }     // HubEventHandler()

        //
        //
        //
        // *************************************************
        // ****             Process Request()           ****
        // *************************************************
        private void ProcessRequest(RequestEventArg <RequestCode> eventArgs)
        {
            switch (eventArgs.RequestType)
            {
            case RequestCode.RequestServers:
                // This is trigger automatically at Start() request.
                // Here, we make all the conenctions necessary for collecting market data, info, etc.

                // Connect to the desired database.
                if (m_DatabaseReader == null)
                {
                    // Search for database service.
                    IService iService = null;
                    if (AppServices.GetInstance().TryGetService("DatabaseReaderWriter", out iService))
                    {       // Found database writer already in services.
                        m_DatabaseReader = (DB.DatabaseReaderWriter)iService;
                        m_DatabaseReader.QueryResponse += new EventHandler(this.HubEventEnqueue);
                    }
                    else
                    {       // Create db our own writer.
                        m_DBInfo = DB.DatabaseInfo.Create(m_DBLocation);
                        AppServices.GetInstance().TryAddService(m_DBInfo);
                        m_DatabaseReader = new DB.DatabaseReaderWriter(m_DBInfo);
                        m_DatabaseReader.QueryResponse += new EventHandler(this.HubEventEnqueue);
                        m_DatabaseReader.Start();
                    }
                    // Request info about exchanges and all products.
                    DB.Queries.QueryBase query = new DB.Queries.ExchangeInfoQuery();
                    m_DatabaseReader.SubmitAsync(query);
                    query = new DB.Queries.ProductInfoQuery();
                    m_DatabaseReader.SubmitAsync(query);
                }
                else
                {
                    Log.NewEntry(LogLevel.Major, "ProcessRequest: Ignoring additional call to RequestServers.");
                }
                break;

            case RequestCode.RequestProducts:
                if (!m_IsDatabaseInitialized)
                {
                    m_PendingRequests.Add(eventArgs);
                }
                else
                {
                }
                break;

            case RequestCode.RequestInstruments:
                if (!m_IsDatabaseInitialized)
                {
                    m_PendingRequests.Add(eventArgs);
                }
                else
                {
                    foreach (object o in eventArgs.Data)
                    {       // Validate this instrument request
                        if (!(o is InstrumentName))
                        {
                            continue;
                        }
                        InstrumentName    instrName = (InstrumentName)o;
                        InstrumentDetails instrDetails;
                        if (!TryGetInstrumentDetails(instrName, out instrDetails) && m_PendingInstrumentQueries.Contains(instrName) != true)
                        {                                              // Details not exist yet and we have not requested them yet.  Request them.
                            Log.NewEntry(LogLevel.Minor, "ProcessRequest: Requesting instr details for {0}.", instrName);
                            m_PendingInstrumentQueries.Add(instrName); // add to pending list (so we can't spam db).
                            DB.Queries.InstrumentInfoQuery query = new DB.Queries.InstrumentInfoQuery();
                            query.InstrumentName = instrName;
                            m_DatabaseReader.SubmitAsync(query);
                        }
                    }    //next data object o
                }
                break;

            case RequestCode.RequestInstrumentPriceSubscription:
                if (!m_IsDatabaseInitialized)
                {
                    m_PendingRequests.Add(eventArgs);
                }
                else
                {
                    foreach (object o in eventArgs.Data)
                    {
                        // Validate this instrument request
                        if (!(o is InstrumentName))
                        {
                            continue;
                        }
                        InstrumentName    instrName = (InstrumentName)o;
                        int               instrId   = 0;
                        InstrumentDetails instrDetails;
                        if (TryLookupInstrumentID(instrName, out instrId) && instrId > -1)
                        {
                            continue;                                   // instrument already has a book id!
                        }
                        // Get the isntrument details first, and make sure details exist.
                        if (!TryGetInstrumentDetails(instrName, out instrDetails))
                        {                                     // Details not exist yet.  Request them.
                            Log.NewEntry(LogLevel.Minor, "ProcessRequest: Need instr details for {0}. Delaying mkt subscription.", instrName);
                            m_PendingRequests.Add(eventArgs); // push onto pending list for later resubmission.
                            base.RequestInstruments(instrName);
                        }
                        else
                        {
                            // Make sure we have not already requested this data.
                            bool isRequestAlreadyPending = false;
                            foreach (DB.Queries.MarketDataQuery query in m_PendingMarketDataQueries)
                            {
                                if (query.InstrumentName == instrName)
                                {
                                    isRequestAlreadyPending = true;
                                    break;
                                }
                            }
                            if (isRequestAlreadyPending)
                            {
                                Log.NewEntry(LogLevel.Major, "ProcessRequest: Market data for {0} pending. Ignore", instrName);
                            }
                            else
                            {       // This request is NOT already pending, so request data now.
                                DB.Queries.MarketDataQuery query = new DB.Queries.MarketDataQuery();
                                query.InstrumentName = instrName;
                                query.StartDate      = m_MktDataStartDateTime.ToUniversalTime(); // Query times in UTC.
                                query.EndDate        = query.StartDate.AddHours(m_MktDataBlockSize);
                                m_PendingMarketDataQueries.Add(query);                           // add to pending list (so we can't spam db).
                                Log.NewEntry(LogLevel.Major, "ProcessRequest: Requesting mkt data for {0} from {1} ({2} hours).", instrName, query.StartDate.ToString("MMM-dd-yyyy HH:mm:ss"), m_MktDataBlockSize);

                                m_DatabaseReader.SubmitAsync(query);
                            }
                        }
                    }
                }

                break;

            case RequestCode.RequestShutdown:
                if (m_DatabaseReader != null)
                {
                    m_DatabaseReader.RequestStop();
                    m_DatabaseReader = null;
                }
                base.Stop();
                break;

            default:
                Log.NewEntry(LogLevel.Major, "ProcessRequest: Unknown request.");
                break;
            } //switch on request type.
        }     // ProcessRequest()