}//SetupInitialize() // // // // // ************************************************ // **** SetupBegin() **** // ************************************************ /// <summary> /// </summary> public override void SetupBegin(IEngineHub myEngineHub, IEngineContainer engineContainer) { // // Master Remote-Engines must send requests to ExecutionHub now. // if (m_IsSubEngine == false) { // Count number of (master) remote engines found in this strategy. // Master remote engines are those connected directly to the Strategy, // without being held by another engine. // Only masters broadcast their xml to the ExecutionHub, and other sub-engine // engines are included as subelements of their master's broadcast. // (If each remote engine broadcasted separately, the ExecHub would have to know how // to put them all back together again... that is, who owned whom.) int remoteMasterEngineCount = 0; foreach (IEngine iEng in engineContainer.GetEngines()) { if (iEng is ExecutionController && ((ExecutionController)iEng).m_IsSubEngine == false) { remoteMasterEngineCount++; } //if (iEng is RemoteEngine) // now count all remote engines // remoteMasterEngineCount++; } // // Create my engine creation request // Dictionary <Type, string[]> rules = new Dictionary <Type, string[]>(); rules.Add(this.GetType(), new string[] { "GetClassName", string.Empty, string.Empty }); string xmlString = Stringifiable.Stringify(this, rules); EngineEventArgs e = new EngineEventArgs(); e.MsgType = EngineEventArgs.EventType.NewEngine; e.Status = EngineEventArgs.EventStatus.Request; e.EngineID = m_EngineID; e.EngineContainerID = m_EngineContainerId; e.DataObjectList = new List <object>(); e.DataObjectList.Add(xmlString); // 0 - engine specs e.DataObjectList.Add(m_LocalEngineHubName); // 1 - engine hub name e.DataObjectList.Add(remoteMasterEngineCount.ToString()); // 2 - number of engines remote hub should expect from this EngineContainer // Send request to remote. if (m_RemoteEngineHub != null && m_RemoteEngineHub.HubEventEnqueue(e)) { Log.NewEntry(LogLevel.Minor, "SetupBegin: Remote-{0} sent creation request to remote.", m_RemoteEngineClassName); } else { Log.NewEntry(LogLevel.Minor, "SetupBegin: Remote-{0} failed to send creation request to remote.", m_RemoteEngineClassName); } } // master remote-engine sends request. } //SetupBegin()
// // // // #endregion//Properties #region Public Methods // ***************************************************************** // **** Public Methods **** // ***************************************************************** // // // ***************************************** // **** Quote() **** // ***************************************** /// <summary> /// Method to request that an order be sent to the Execution hub at /// a particular price and qty. /// </summary> /// <param name="orderSide"></param> /// <param name="price"></param> /// <param name="qty"></param> /// <param name="quoteReason"></param> /// <returns>TradeId</returns> public int Quote(int orderSide, double price, int qty, string quoteReason) { m_EngineEventArgsForOrders[orderSide].DataObjectList.Clear(); //clear before each use! // Locate TradeEventArg to update. SyntheticOrder syntheticOrder = null; if (m_ActiveOrders[orderSide] == null) { // There is currently no active trade, so create one. syntheticOrder = SyntheticOrder.RequestNewOrder(++m_LastOrderId); syntheticOrder.Side = orderSide; syntheticOrder.TradeReason = quoteReason; m_ActiveOrders[orderSide] = syntheticOrder; // store it as active trade } else { // There is already an active trade, grab it. syntheticOrder = m_ActiveOrders[orderSide]; } // Update quatities if they have changed. // TODO: implement various round-off schemes. int tradeSign = QTMath.MktSideToMktSign(orderSide); int iPrice = tradeSign * (int)System.Math.Floor(tradeSign * price / m_QuoteTickSize); // integerized price! bool isChangedFromPrev = qty != m_QuoteQtyPrev[orderSide] || (iPrice != m_QuoteIPricePrev[orderSide]) || quoteReason != m_QuoteReasonPrev[orderSide]; if (isChangedFromPrev) { m_QuoteQtyPrev[orderSide] = qty; m_QuoteIPricePrev[orderSide] = iPrice; m_QuoteReasonPrev[orderSide] = quoteReason; syntheticOrder.Price = iPrice * m_QuoteTickSize; syntheticOrder.Qty = qty; syntheticOrder.TradeReason = quoteReason; m_EngineEventArgsForOrders[orderSide].DataObjectList.Add(syntheticOrder); // add to event arg that is already set up. m_ExecutionHub.HubEventEnqueue(m_EngineEventArgsForOrders[orderSide].Copy()); // send off to remote exeuction m_StrategyHub.Log.NewEntry(Lib.Hubs.LogLevel.Major, "TradeEngine: {0} sent {1} ", m_Strategy.Name, syntheticOrder); } // Exit if (syntheticOrder == null) { return(-1); } else { return(syntheticOrder.OrderId); } }// Quote()
// // // ************************************************ // **** MenuItem_CLick **** // ************************************************ /// <summary> /// This event handles all Menu Item selections by user. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MenuItem_CLick(object sender, EventArgs e) { if (sender is ToolStripMenuItem) { ToolStripMenuItem menuItem = (ToolStripMenuItem)sender; if (menuItem == menuItemNewGraphWindow) { NewGraphWindow_Click(sender, e); } else if (menuItem == menuItemSaveStrategies) { if (AssocEngineHub != null) { AssocEngineHub.HubEventEnqueue(EngineEventArgs.RequestSaveEngines(AssocEngineHub.ServiceName)); } } } }
} //ProcessEngineEvents() // // // // ***************************************************************** // **** Process FrontEndRequest **** // ***************************************************************** /// <summary> /// These are my internal requests, used to create new GUI displays, etc. /// </summary> /// <param name="request"></param> private void ProcessFrontEndRequest(FrontEndRequest request) { EngineEventArgs e; Log.NewEntry(LogLevel.Minor, "FrontEndRequest {0}", request.ToString()); switch (request.Type) { case FrontEndRequest.Request.Start: // ************************************ // *** Start *** // ************************************ m_ServiceState = ServiceStates.Running; // We are ready to run. OnServiceStateChanged(); break; case FrontEndRequest.Request.Stop: // ************************************ // *** Stop *** // ************************************ if (m_ServiceState != ServiceStates.Stopping) { // Shut down displays m_ServiceState = ServiceStates.Stopping; // Trying to stop. OnServiceStateChanged(); // Tell displays to shut down. foreach (ClusterDisplay display in m_ClusterDisplays.Values) { if (display != null && (!display.IsDisposed)) { try { display.Invoke((System.Threading.ThreadStart) delegate() { display.Close(); }); } catch (Exception) { } } } } // Verify we can stop. if (m_ClusterDisplays.Count == 0) { // All displays are removed and shutdown. We can exit now. m_ServiceState = ServiceStates.Stopped; OnServiceStateChanged(); base.Stop(); } else { Log.NewEntry(LogLevel.Major, "Shutting down. {0} displays remaining.", m_ClusterDisplays.Count); m_PendingRequests.Enqueue(request); } break; case FrontEndRequest.Request.AddService: // ************************************ // *** Add Service *** // ************************************ // This is called internally, each time a new service is added // to the application. We attempt to get information about it. if (request.ObjectList == null) { return; } for (int i = 0; i < request.ObjectList.Count; ++i) { string serviceName = (string)request.ObjectList[i]; bool isGoodToAdd = true; // First check whether this type of engine is we want to ignore. foreach (string pattern in m_IgnoreEngineNamePatterns) { if (serviceName.Contains(pattern)) { isGoodToAdd = false; break; } } if (isGoodToAdd == false) { return; } IService iService; if (m_AppServices.TryGetService(serviceName, out iService) && iService is IEngineHub) { // We have discovered a new EngineHub if (!m_RemoteEngineHubs.ContainsKey(serviceName)) { // This new engineHub isunknown to us. IEngineHub iEngine = (IEngineHub)iService; m_RemoteEngineHubs.Add(serviceName, iEngine); Log.NewEntry(LogLevel.Major, "Adding new EngineHub {0}. Requesting all controls.", serviceName); iEngine.EngineChanged += new EventHandler(this.HubEventEnqueue); e = EngineEventArgs.RequestAllControls(serviceName); iEngine.HubEventEnqueue(e); } } } break; case FrontEndRequest.Request.AddDisplay: // ************************************ // *** Add Display *** // ************************************ // When a new display is requested, we search for the GuiTemplates already // stored for that new display, create the display and hand them to the display. List <string> engineHubNames = new List <string>(); if (request.ObjectList == null || (request.ObjectList.Count == 1 && request.ObjectList[0] == null)) { engineHubNames.AddRange(m_RemoteEngineHubs.Keys); } else { foreach (object o in request.ObjectList) { if (o is string) { engineHubNames.Add((string)o); } } } // Open displays for each hub name provided. foreach (string engineName in engineHubNames) { Dictionary <int, GuiTemplates.EngineContainerGui> engineHubTemplates = null; IEngineHub iEngineHub = null; if (m_RemoteEngineHubs.TryGetValue(engineName, out iEngineHub) && m_EngineHubTemplates.TryGetValue(engineName, out engineHubTemplates)) { Log.NewEntry(LogLevel.Major, "AddDisplay requesting new ClusterDisplay for {0}.", engineName); List <GuiTemplates.EngineContainerGui> templates = new List <GuiTemplates.EngineContainerGui>(engineHubTemplates.Values); Utilities.GuiCreator creator = Utilities.GuiCreator.Create(typeof(ClusterDisplay), this, iEngineHub, templates); creator.FormCreated += new EventHandler(this.HubEventEnqueue); // push created form on to my usual queue. creator.Start(); } else { Log.NewEntry(LogLevel.Major, "AddDisplay request rejected for {0}. No templates found.", engineName); } } break; case FrontEndRequest.Request.RemoveDisplay: // ************************************ // *** Remove Display *** // ************************************ ClusterDisplay display2 = (ClusterDisplay)request.ObjectList[0]; int n = display2.ID; if (m_ClusterDisplays.ContainsKey(n)) { m_ClusterDisplays.Remove(n); Log.NewEntry(LogLevel.Major, "RemoveDisplay id {1}. Remaining {0}.", m_ClusterDisplays.Count, n); } break; default: Log.NewEntry(LogLevel.Warning, "Unknown request."); break; } //requestType switch } //ProcessFrontEndRequest().
// // #endregion//Public Methods #region HubEvent Handler // ***************************************************************** // **** Private HubEvent Methods **** // ***************************************************************** // // // **** Hub Event Handler **** // /// <summary> /// Main request handling routine. /// Called only by the internal hub thread. /// </summary> /// <param name="e"></param> protected override void HubEventHandler(EventArgs[] eArgList) { foreach (EventArgs eArg in eArgList) // process each event { Log.NewEntry(LogLevel.Minor, eArg.ToString()); Type eArgType = eArg.GetType(); if (eArgType == typeof(FrontEndHub.DisplayArgs)) { // **************************************** // **** Display Events **** // **************************************** // These are my internal requests, used to create new GUI displays, etc. FrontEndHub.DisplayArgs e = (FrontEndHub.DisplayArgs)eArg; switch (e.Request) { case DisplayArgs.DisplayRequest.NewDisplay: // // *** New Display *** // // When a new display is requested (to be displayed from this hub), a request is pushed // onto the queue and comes here. this way the new ClusterDisplay can be created and // added to the list without the need to lock the list (only the hub thread ever touches // this list.) IEngineHub engineHub = e.display.AssocEngineHub; // hub whose elements we want to display List <ClusterDisplay> displayList; // displays already associated with element hub if (!m_EngineSubscriptions.TryGetValue(engineHub, out displayList)) { // First time we are creating a display for this hub. There is no existing list. displayList = new List <ClusterDisplay>(); // create new list. m_EngineSubscriptions.Add(engineHub, displayList); engineHub.EngineChanged += new EventHandler(this.HubEventEnqueue); } ClusterDisplay newDisplay = e.display; // display created by event creator. displayList.Add(newDisplay); m_ClusterDisplay.Add(newDisplay.ID, newDisplay); // the ID is made by original caller // Now request a complete list of the controls for engines from hub. engineHub.HubEventEnqueue(Engines.EngineEventArgs.RequestAllControls(newDisplay.ID - newDisplay.prevGuiTurns)); //newDisplay.ID)); break; case DisplayArgs.DisplayRequest.RemoveDisplay: // // *** Remove Display *** // ClusterDisplay displayToRemove = e.display; if (displayToRemove != null) { // Remove any book subscriptions List <object> hubsToRemove = new List <object>(); foreach (BookHub hub in m_Subscriptions.Keys) { if (m_Subscriptions[hub].Contains(displayToRemove)) { m_Subscriptions[hub].Remove(displayToRemove); if (m_Subscriptions[hub].Count == 0) { hub.InstrumentChanged -= this.HubEventEnqueue; hubsToRemove.Add(hub); } } } foreach (object hub in hubsToRemove) { m_Subscriptions.Remove((BookHub)hub); } // Remove engine subscriptions foreach (IEngineHub hub in m_EngineSubscriptions.Keys) { if (m_EngineSubscriptions[hub].Contains(displayToRemove)) { m_EngineSubscriptions[hub].Remove(displayToRemove); if (m_EngineSubscriptions[hub].Count == 0) { hub.EngineChanged -= this.HubEventEnqueue; hubsToRemove.Add(hub); } } } foreach (object hub in hubsToRemove) { m_EngineSubscriptions.Remove((IEngineHub)hub); } m_ClusterDisplay[displayToRemove.ID] = null; // dump my pointer to it. } break; default: // // *** default error *** // Log.NewEntry(LogLevel.Error, "Unknown DisplayArg Request."); break; } } else if (eArgType == typeof(EngineEventArgs)) { // ***************************************************** // ***** Process Engine Events **** // ***************************************************** EngineEventArgs e = (EngineEventArgs)eArg; // Pass event to all ClusterDisplays subscribed to event-generating hub. // List <ClusterDisplay> clusterDisplayList; if (m_EngineSubscriptions.TryGetValue(e.EngineHubResponding, out clusterDisplayList)) { // at least some displays are subscribed to this hub. for (int i = 0; i < clusterDisplayList.Count; ++i) { ClusterDisplay display = clusterDisplayList[i]; //List<IEngineContainer> containers = display.GetEngineContainers(); // get containers in this hub. //Dictionary<int, IEngineContainer> containersDict = display.GetEngineContainersDictionary(); //IEngineContainer engineContainer11; if (e.EngineContainerID < 0) { // EngineContainer ID < 0 => event is meant for all containers in hub. // Such events are passed to all Stratgies or Clusters, etc. if (e.MsgType == EngineEventArgs.EventType.GetControls) { // Create the cluster controls for this display. // This request is made by ClusterDisplays (to the Hub they are displaying) after // they have been created, but not completely initialized. // Now proceed through our list of ClusterDisplays and only the first uninitialized // display we find will have the controls inside this eventarg passed to it. bool isNewDisplay = (e.Status == EngineEventArgs.EventStatus.Confirm) && (!display.IsInitialized); if (isNewDisplay) { display.HubEventEnqueue(e); // This is a non-asynchronous call, display is initialized immediately. // Now request all parameter updates for new display. List <EngineEventArgs> newRequestList = EngineEventArgs.RequestAllParameters((display.ID - display.prevGuiTurns), display); //(i,display); foreach (EngineEventArgs newRequest in newRequestList) { e.EngineHubResponding.HubEventEnqueue(newRequest); } break; // only initialize one display per GetControls event. The first uninitialized display gets initialized. } } else { // Every other non-GetControls event for "all clusters" processed here. // Right now, there are none of such terms. List <IEngineContainer> containers = display.GetEngineContainers(); // get containers in this hub. foreach (IEngineContainer container in containers) { container.ProcessEngineEvent(e); } } } else { // A specific containerID was provided. // Pass along this event directly to the specific engineContainer. Dictionary <int, IEngineContainer> containersDict = display.GetEngineContainersDictionary(); IEngineContainer engineContainer; if (containersDict.TryGetValue(e.EngineContainerID, out engineContainer)) { engineContainer.ProcessEngineEvent(e); } else { // Failed to find enginecontainer! Log.NewEntry(LogLevel.Error, "Received event for unknown engineContainerID={0}.", e.EngineContainerID); } } display.RegenerateNow(this, null); // tells the display to repaint, if needed. } } } else { // // **** Unrecognized Event **** // Log.NewEntry(LogLevel.Error, "Unknown event type: {0}", eArgType.ToString()); eArg.GetType(); } } //next event arg } //HubEventHandler()