/// <summary> /// Thread to hold the dialog that hosts the eSignal ActiveX control /// </summary> private static void RealTimePriceThread() { if (eSignal != null) { MarkThree.EventLog.Information("Real Time Price service is already started... ignoring Start request."); return; } // create an instance of eSignal and set delegates for events eSignal = new ESignal(); eSignal.OnConnectChangeDM += new ESignal.DMConnectHandler(RealTimePricing.OnConnectionChangeDM); eSignal.OnUpdateSymbolDM += new ESignal.DMUpdateSymbolHandler(RealTimePricing.OnUpdateSymbolDM); // connect to the local eSignal data manager // If connect succeeds, then we add the symbols to the data manager from the connect // handler. eSignal.Connect(dataManager.Username, dataManager.Password); // by this point, we've loaded all of the symbols into the data manager. // if we have an esignal, then we run the form to allow the event loop to start if (eSignal != null) { // NOTE: I don't think this does anything, because the application // will display the form in the run method eSignal.Visible = false; // RealTimePricing will now just wait for connect/update events. // *** the thread blocks here Application.Run(eSignal); } }
/// <summary> /// Terminates the simulation of a price feed. /// </summary> /// <param name="transaction">Used to commit or reject one or more operations as a unit.</param> /// <param name="remoteMethod">A metadata description of the method to be executed.</param> public static void Stop(ParameterList parameters) { MarkThree.EventLog.Information("Stopping Real Time Price service."); // stop the local eSignal data manager (if we started it) dataManager.Stop(); // if we have a running thread, abort it if (priceThread != null) { // disconnect from the local eSignal data manager if (eSignal != null) { eSignal.Disconnect(); } // exit the application - this will stop the thread blocked at // Application.Run() from RealTimePricing.Start() Application.Exit(); MarkThree.EventLog.Information("Real Time Price service stopped."); } else { MarkThree.EventLog.Information("Real Time Price can NOT stop because the service is not running."); } // nullify the eSignal and thread objects... so it can be started again symbolToSecurityIdTable.Clear(); // empty the symbol list mapping eSignal = null; priceThread = null; }
/// <summary> /// Loads a DataSet from the XML file defined by symbolFilepath. Iterates through each (configurationId, equityId) pair /// and adds the ticker symbol to the eSignal Data Manager watch list. /// </summary> private static void LoadSymbols() { try { // Lock the tables. // Acquire the configuration and object locks for the securityId lookup Debug.Assert(!ServerMarketData.IsLocked); ServerMarketData.SecurityLock.AcquireReaderLock(Timeout.Infinite); ServerMarketData.EquityLock.AcquireReaderLock(Timeout.Infinite); ServerMarketData.ObjectLock.AcquireReaderLock(Timeout.Infinite); ServerMarketData.ConfigurationLock.AcquireReaderLock(Timeout.Infinite); // initialize the dataset from the XMl file DataSet dataSetFromXML = new DataSet("SP500"); dataSetFromXML.ReadXml(symbolFilepath, XmlReadMode.InferSchema); foreach (DataRow dataRow in dataSetFromXML.Tables["method"].Rows) { // extract the configurationId and the externalEquityId from the dataset object configurationId = dataRow["configurationId"]; string externalEquityId = (string)dataRow["equityId"]; try { // look up the equityId int equityId = (int)Security.FindOptionalKey(configurationId, "equityId", externalEquityId); // get the equity row ServerMarketData.EquityRow equityRow = ServerMarketData.Equity.FindByEquityId(equityId); if (equityRow != null) { // Get the security row from the equity row ServerMarketData.SecurityRow securityRow = equityRow.SecurityRowBySecurityEquityEquityId; // attempt to add the symbol to the eSignal data manager if (eSignal.AddRealTimeSymbol(securityRow.Symbol)) { symbolToSecurityIdTable[securityRow.Symbol] = securityRow.SecurityId; } else { MarkThree.EventLog.Warning("Market Data Service has no data for ticker {0}", externalEquityId); } } } catch (Exception exception) { // Write the error to the log. MarkThree.EventLog.Error("{0}, {1}", exception.Message, exception.StackTrace); } } // Mark the time that the real-time updates started. MarkThree.EventLog.Information("Real Time Symbols Loaded"); } catch (Exception exception) { eSignal = null; // Write the error and stack trace out to the debug listener MarkThree.EventLog.Warning(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); } finally { // Release the global tables. //if (ServerMarketData.PriceLock.IsWriterLockHeld) ServerMarketData.PriceLock.ReleaseWriterLock(); if (ServerMarketData.SecurityLock.IsReaderLockHeld) { ServerMarketData.SecurityLock.ReleaseReaderLock(); } if (ServerMarketData.EquityLock.IsReaderLockHeld) { ServerMarketData.EquityLock.ReleaseReaderLock(); } if (ServerMarketData.ObjectLock.IsReaderLockHeld) { ServerMarketData.ObjectLock.ReleaseReaderLock(); } if (ServerMarketData.ConfigurationLock.IsReaderLockHeld) { ServerMarketData.ConfigurationLock.ReleaseReaderLock(); } Debug.Assert(!ServerMarketData.IsLocked); } }