/// <summary> /// The GetDictionaryFromField method is invoked to attempt /// to determine which dictionary associated with a specific /// version definition contains a specific FIX field. /// </summary> /// <param name="version"> /// The FIX version definition to search. /// </param> /// <param name="tag"> /// The FIX tag of the element to search for. /// </param> /// <returns> /// The first dictionary in the version definition that has /// a field definition that matches the specified tag. /// </returns> public FixDictionary GetDictionaryFromField(string version, int tag) { FixDictionary result = null; if (_vxRegistry != null) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { if (_dxRegistry != null) { foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); if (dxInstance != null) { if (dxInstance.Fields.GetElement(tag) != null) { result = dxInstance; break; } } } } } } return(result); }
/// <summary> /// The Init method is invoked to initialize an instance /// of the matcher with a version definition registry that /// it can use to lookup information about vesions as it is /// matching messages. /// </summary> /// <param name="registry"> /// The version definition registry that the matcher is to /// use when looking up version information. /// </param> public void Init(IVfxFixVxRegistry registry) { // REC: Iterate over all of the version definitions // in the registry and construct corresponding match // entries for the matcher: foreach (VfxFixVxRecord vxRecord in registry) { // REC: The version name: string vxName = vxRecord.Name; MatchEntry matchEntry = new MatchEntry(); matchEntry.Name = vxName; VfxFixVxRecord vxDetails = registry.Get(vxName); foreach (VfxFixVersion_Rule vxRule in vxDetails.Rules) { matchEntry.Rules.Add(vxRule); } if (!_mapLayers.ContainsKey(vxDetails.Layer)) { _mapLayers.Add(vxDetails.Layer, new List <MatchEntry>()); } _mapLayers[vxDetails.Layer].Add(matchEntry); } }
/// <summary> /// The HandleIpc_EventOpened method is invoked in response /// to the IPC endpoint establishing a connection to the peer /// system that the service is interacting with. /// </summary> /// <param name="sender"> /// The VfxIpcEndpoint that dispatched the event. /// </param> /// <param name="args"> /// The details associated with the event. /// </param> private void HandleIpc_EventOpened(object sender, VfxIpcEventArgs args) { lock (_synch) { // REC: The IPC session is now established. _ipcEstablished = true; // REC: Adjust the service's current status: _serviceStatus = VfxFixServiceStatus.Service_Status_Opened; // REC: Dispatch the update to the service's subscribers: EventHandler <VfxFixServiceEventArgs> tmpDispatch_Update = EventDispatch; if (tmpDispatch_Update != null) { VfxFixServiceEventArgs tmpArgs = new VfxFixServiceEventArgs(VfxFixServiceEventTypes.Event_Service_Updated, _serviceStatus); tmpDispatch_Update(this, tmpArgs); } // REC: Retrieve the version definition from the version // definition registry and determine what kind of session // needs to be created in order to handle the connection: IVfxFixVxRegistry vxRegistry = this._localServices.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry; // REC: Create a new instance of a FIX session to handle // the communication between the server and the peer: IVfxFixSession fixSession = null; // REC: Check the version definition in order to tell if // this is a FIX 4.x or FIX 5.x service: VfxFixVxRecord vxRecord = vxRegistry.Get(this._sxVersion); if (vxRecord.Layer.ToLower().CompareTo("combined") == 0) { fixSession = new VfxFix4xClientSession(); } else { fixSession = new VfxFix5xClientSession(); } _fixSession = fixSession; // REC: Initialize the session: _fixSession.Init(this._localServices, this); // REC: Construct an instance of the session wrapper // for the FIX application and bind it to the session // implementation that has been created: _appSession = new VfxFixClientSession(_fixSession); // REC: Notify the FIX session implementation that it // has been connected to a peer system: _fixSession.HandleConnect(); } }
/// <summary> /// The HandleIpcDispatch_EventOpened event handler is invoked in /// response to a new session being established between a peer /// system and the endpoint associated with the service. /// </summary> /// <param name="sender"> /// The IPC endpoint that dispatched the event. /// </param> /// <param name="args"> /// The details of the event being dispatched. /// </param> private void HandleIpcDispatch_EventOpened(object sender, VfxIpcEventArgs args) { // REC: Create a new instance of a FIX session to handle // the communication between the server and the peer: IVfxFixSession fixSession = null; // REC: Retrieve the version definition from the version // definition registry and determine what kind of session // needs to be created in order to handle the connection: IVfxFixVxRegistry vxRegistry = this._localServices.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry; // REC: Check the version definition in order to tell if // this is a FIX 4.x or FIX 5.x service: VfxFixVxRecord vxRecord = vxRegistry.Get(this._sxVersion); if (vxRecord.Layer.ToLower().CompareTo("combined") == 0) { fixSession = new VfxFix4xServerSession(); } else { fixSession = new VfxFix5xServerSession(); } // REC: Initialize the session: fixSession.Init(_localServices, this); // REC: Create an entry for the session in the // local session map: _mapFixSessions.Add(fixSession.InstanceId, fixSession); // REC: Bind the FIX session to the IPC session: _mapFixToIpc.Add(fixSession.InstanceId, args.Token); // REC: Bind the IPC session to the FIX session: _mapIpcToFix.Add(args.Token, fixSession.InstanceId); // REC: Create the application session container // that will be passed to the app implementation // when events are generated on the session: VfxFixServerSession appSession = new VfxFixServerSession(fixSession); // REC: Create a binding between the FIX session // and the application session so that events from // the FIX session can be correlated to the correct // application session when events are dispatched to // the user's FIX application instance: _mapAppSessions.Add(fixSession.InstanceId, appSession); // REC: Inform the session that a peer system // has been connected to it: fixSession.HandleConnect(); }
/// <summary> /// The Init method is invoked to initialize an instance of /// the session class with the services, setttings, and handler /// that it requires in order to be activated. All instances of /// a session must be initialized before they can start managing /// a FIX session for their owner. /// </summary> /// <param name="services"> /// The service container that contains the references to all of /// the system services that an instance of the session needs. /// </param> /// <param name="handler"> /// The callback interface that the session directs all of its /// events to as they occur. /// </param> public void Init(IVfxServices services, IVfxFixSessionHandler handler) { // REC: Retrieve the version registry that the session // has been configured to use: IVfxFixVxRegistry vxRegistry = services.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry; // REC: Retrieve the dictionary registry that the session // has been configured to use: IVfxFixDxRegistry dxRegistry = services.GetService(typeof(IVfxFixDxRegistry)) as IVfxFixDxRegistry; // REC: Retrieve the session database service from the // set of services provided by the session's owner: _fixDatabase = services.GetService(typeof(IVfxFixDatabase)) as IVfxFixDatabase; // REC: Retrieve the session configuration from the // service container for relevant settings: IVfxSettings settings = services.GetService(typeof(IVfxSettings)) as IVfxSettings; // REC: Temporary container to simplify accessing the // session settings from the XML configuration document: Dictionary <string, string> mapSettings = new Dictionary <string, string>(); XPathNavigator xpn = settings.Document.CreateNavigator(); XPathNodeIterator xpi; xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Sx.Version']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { this._sxVersion = xpi.Current.GetAttribute("content", "").Trim(); } xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Ax.Version']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { this._axVersion = xpi.Current.GetAttribute("content", "").Trim(); } // REC: Retrieve application layer details: VfxFixVxRecord axDetails = vxRegistry.Get(_axVersion); // REC: Adjust the session layer, if one has not been // specified for the connection. if (string.IsNullOrEmpty(this._sxVersion)) { if (axDetails.Layer.ToLower().CompareTo("combined") == 0) { this._sxVersion = this._axVersion; } } // REC: Retrieve the session layer details: VfxFixVxRecord sxDetails = vxRegistry.Get(_sxVersion); // REC: Construct a local instance of a version definition // registry so that the session relies only on the specific // versions that have been specified for the service: VfxFixVxRegistry localVxRegistry = new VfxFixVxRegistry(); // REC: Add the session layer to the local registry: localVxRegistry.Add(this._sxVersion, sxDetails); // REC: Add the application layer to the local registry: localVxRegistry.Add(this._axVersion, axDetails); // REC: Construct a new instance of the service container // and populate it with the services for the session: IVfxServices localServices = new VfxServices(); // REC: The session can use the global dictionaries: localServices.AddService(typeof(IVfxFixDxRegistry), dxRegistry); // REC: The session can use its own version registry: localServices.AddService(typeof(IVfxFixVxRegistry), localVxRegistry); // REC: Initialize the parser with the local services: _fixParser.Init(localServices); // REC: Configure the FIX session timer to fire every // second for conducting timeout checks, etc. _fixTimer.Interval = 1000; // REC: Subscribe to the timer in order to determine if // the session has timed out: this._fixTimer.Elapsed += HandleElapsed_Timer; // REC: Initialize the FIX message assembler: _fixAssembler.Init(localServices); // REC: Register required fields for messages: this._fixBeginString = sxDetails.FixBs; _fixAssembler.SetField(new FixField(8, this._fixBeginString)); _fixAssembler.SetField(new FixField(9, "")); _fixAssembler.SetField(new FixField(98, "0")); _fixAssembler.SetField(new FixField(108, "60")); xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Heartbeat']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { string fixTimeout = xpi.Current.GetAttribute("content", "").Trim(); // REC: The client sessions need to maintain their own // reference to the heartbeat value: this._fixTimeout = int.Parse(fixTimeout); // REC: Assign the timeout value to the assembler so it // becomes the default for any message that needs it: _fixAssembler.SetField(new FixField(108, fixTimeout)); } xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.SenderCompID']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { // REC: The client sessions need to maintain an independent // reference to the SenderCompID for identification: this._fixSenderCompID = xpi.Current.GetAttribute("content", ""); // REC: Add the field to the assembler so that it gets put // into each outgoing message: _fixAssembler.SetField(new FixField(49, this._fixSenderCompID)); } xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.TargetCompID']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { // REC: The client sessions need to maintain an independent // reference to the TargetCompID for identification: this._fixTargetCompID = xpi.Current.GetAttribute("content", ""); // REC: Add the field to the assembler so that it gets put // into each outgoing message: _fixAssembler.SetField(new FixField(56, this._fixTargetCompID)); } _fixAssembler.SetField(new FixField(10, "")); // REC: The client session knows the FIX TargetCompID of the // peer system in advance, unlike the server sessions, so we // can construct the session id in the initialization code: _sessionId = string.Format("{0}-{1}", _fixSenderCompID, _fixTargetCompID); // REC: Maintain a reference to the supplied callback // handler for issuing event notifications: _handler = handler; }
void IVfxFixSession.Init(IVfxServices services, IVfxFixSessionHandler handler) { // REC: Maintain a reference to the set of configuration settings // that are supplied to the session instance: _localServices = services; // REC: Retrieve the version registry that the session // has been configured to use: IVfxFixVxRegistry vxRegistry = services.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry; // REC: Retrieve the dictionary registry that the session // has been configured to use: IVfxFixDxRegistry dxRegistry = services.GetService(typeof(IVfxFixDxRegistry)) as IVfxFixDxRegistry; // REC: Retrieve the session database service from the // set of services provided by the session's owner: _fixDatabase = services.GetService(typeof(IVfxFixDatabase)) as IVfxFixDatabase; // REC: Retrieve the configuration settings and extract // the FIX session and application layer versions: IVfxSettings settings = this._localServices.GetService(typeof(IVfxSettings)) as IVfxSettings; XPathNavigator xpn = settings.Document.CreateNavigator(); XPathNodeIterator xpi; xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Sx.Version']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { this._sxVersion = xpi.Current.GetAttribute("content", "").Trim(); } xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Ax.Version']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { this._axVersion = xpi.Current.GetAttribute("content", "").Trim(); } // REC: Retrieve application layer details: VfxFixVxRecord axDetails = vxRegistry.Get(_axVersion); // REC: Adjust the session layer, if it was not specified // and the application layer is FIX 4.0-4.4: if (string.IsNullOrEmpty(this._sxVersion)) { if (axDetails.Layer.ToLower().CompareTo("combined") == 0) { this._sxVersion = this._axVersion; } } // REC: Retrieve the session layer details: VfxFixVxRecord sxDetails = vxRegistry.Get(_sxVersion); // REC: Construct a local instance of a version definition // registry so that the session relies only on the specific // versions that have been specified for the service: VfxFixVxRegistry localVxRegistry = new VfxFixVxRegistry(); // REC: Add the session layer to the local registry: localVxRegistry.Add(this._sxVersion, sxDetails); // REC: Add the application layer to the local registry: localVxRegistry.Add(this._axVersion, axDetails); // REC: Construct a new service container and initialize // it with the appropriate services: IVfxServices localServices = new VfxServices(); localServices.AddService(typeof(IVfxFixDxRegistry), dxRegistry); localServices.AddService(typeof(IVfxFixVxRegistry), localVxRegistry); // REC: Initialize the parser with the local services: _fixParser.Init(localServices); // REC: Configure the FIX session timer to fire every // second for conducting timeout checks, etc. _fixTimer.Interval = 1000; // REC: Subscribe to the timer in order to determine if // the session has timed out: _fixTimer.Elapsed += HandleElapsed_Timer; // REC: Construct the FIX BeginString using the major // and minor version numbers from the primary dictionary // that is assigned to the version: FixDictionary dxPrimary = dxRegistry.GetEntry(sxDetails.Dictionaries[0].Name); // REC: Construct the appropriate begin string, based on the // major and minor version numbers of the dictionary: this._fixBeginString = sxDetails.FixBs; _fixAssembler.SetField(new FixField(8, this._fixBeginString)); // REC: Initialize the FIX message assembler: _fixAssembler.Init(localServices); // REC: Register required fields for messages: _fixAssembler.SetField(new FixField(8, _fixBeginString)); _fixAssembler.SetField(new FixField(9, "")); _fixAssembler.SetField(new FixField(98, "0")); _fixAssembler.SetField(new FixField(10, "")); xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.SenderCompID']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { // REC: The client sessions need to maintain an independent // reference to the SenderCompID for identification: this._fixSenderCompID = xpi.Current.GetAttribute("content", ""); // REC: Add the field to the assembler so that it gets put // into each outgoing message: _fixAssembler.SetField(new FixField(49, this._fixSenderCompID)); } xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Reset']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { string resetSequence = xpi.Current.GetAttribute("content", ""); if (resetSequence.CompareTo("true") == 0) { this._resetSequence = true; } } // REC: Maintain a reference to the supplied callback // handler for issuing event notifications: _handler = handler; }
/// <summary> /// The PopulateHdrElements method populates the header section /// of a FIX message with the header elements from the specified /// version of the FIX protocol. /// </summary> /// <param name="version"> /// The version of the FIX protocol that is used to populate the /// header elements of the message. /// </param> /// <param name="msg"> /// The FIX message instance that is to be populated with all of /// the header elements from the specific FIX version. /// </param> private void PopulateHdrElements(string version, FixMessage msg) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { // REC: Ensure that there is at least one FIX dictionary // assigned to the specified version definition: if (vxDetails.Dictionaries.Count > 0) { FixDictionary dxEntry = _dxRegistry.GetEntry(vxDetails.Dictionaries[0].Name); if (dxEntry != null) { FixDxCollection hdrElements = dxEntry.Resolve(dxEntry.Header); if (hdrElements != null) { // REC: Create the sort ordering for the elements // and populate any fields and groups that have been // registered with the assembler: Collection <int> ordering = new Collection <int>(); foreach (IFixDxElement dxElement in hdrElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Header.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Header.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Header.SetOrdering(ordering); } } else { string error = string.Format("Dictionary \"{0}\" not registered.", vxDetails.Dictionaries[0]); throw new ArgumentException(error); } } else { string error = string.Format("The version \"{0}\" has no associated dictionaries.", version); throw new ArgumentException(error); } } else { string error = string.Format("The version \"{0}\" is not registered.", version); throw new ArgumentException(error); } }
public void Init(IVfxServices services, XmlDocument settings) { // REC: The client service creates its own instance of a // service container and populates it with references to // both application and local service references: _localServices = new VfxServices(); // REC: Maintain a reference to the configuration that is // provided by the caller - this will be used to configure // the sessions that are created when clients connect to an // instance of the service: _localServices.AddService(typeof(IVfxSettings), new VfxSettings(settings)); // REC: Retrieve the IVfxFixApp service and maintain a // reference to it so that events from the FIX sessions // can be routed to the user's application: _application = services.GetService(typeof(IVfxFixApp)) as IVfxFixApp; if (_application == null) { throw new ArgumentException("The IVfxFixApp service must be provided."); } // REC: Ensure that the FIX version registry has been provided // in the service container that was supplied by the caller: IVfxFixVxRegistry vxRegistry = services.GetService(typeof(IVfxFixVxRegistry)) as IVfxFixVxRegistry; if (vxRegistry == null) { throw new ArgumentException("The IVfxFixVxRegistry service is not available."); } // REC: Ensure that the FIX dictionary registry has been provided // in the service container that was supplied by the caller: IVfxFixDxRegistry dxRegistry = services.GetService(typeof(IVfxFixDxRegistry)) as IVfxFixDxRegistry; if (dxRegistry == null) { throw new ArgumentException("The IVfxFixDxRegistry service is not available."); } // REC: An XPathNavigator is used to retrieve all of the // relevant settings from the corresponding configuration // document that is provided by the settings instance: XPathNavigator xpn = settings.CreateNavigator(); // REC: An XPathNodeIterator is used to retrieve all of // the relevant settings from the document. The instance // is created by calling the 'Select' method of the path // navigator that is created from the settings: XPathNodeIterator xpi = null; xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Sx.Version']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { this._sxVersion = xpi.Current.GetAttribute("content", "").Trim(); } xpi = xpn.Select("/Session/Protocol/Settings/Setting[@name='Fix.Session.Ax.Version']"); if ((xpi.Count > 0) && (xpi.MoveNext())) { this._axVersion = xpi.Current.GetAttribute("content", "").Trim(); } // REC: Attempt to retrieve the version information that // corresponds to the configured application layer: VfxFixVxRecord vxRecord = vxRegistry.Get(this._axVersion); if (vxRecord == null) { throw new ArgumentException("The specified application layer could not be resolved."); } // REC: If the session layer version of the protocol // has not been specified, this may indicate that the // application version is FIX 4.0-4.4. If that is the // case, then we can default the session layer to the // same version as the application layer: if (string.IsNullOrEmpty(this._sxVersion)) { // REC: The layer "combined" is set on version definitions // to indicate that both the session layer and application // layer are defined within the same dictionary: if (vxRecord.Layer.ToLower().CompareTo("combined") == 0) { this._sxVersion = this._axVersion; } else { // REC: If the application layer does not resolve to // an instance of a version definition that represents // a version of FIX earlier than 5.0, then the service // cannot be configured based on the app layer: throw new ArgumentException("The session layer must be specified..."); } } // REC: Retrieve the endpoint configuration from the session // configuration and use it to create a new instance of that // type of endpoint: xpi = xpn.Select("/Session/Endpoint"); if ((xpi.Count == 1) && (xpi.MoveNext())) { XmlDocument epxConfiguration = new XmlDocument(); epxConfiguration.LoadXml(xpi.Current.OuterXml); this._endpoint = VfxEndpointFactory.Create(epxConfiguration); } this._endpoint.EventDispatch += HandleIpcDispatch; this._localServices.AddService(typeof(IVfxFixVxRegistry), vxRegistry); this._localServices.AddService(typeof(IVfxFixDxRegistry), dxRegistry); // REC: Retrieve the session database configuration from // the configuration settings: xpi = xpn.Select("/Session/Database"); if ((xpi.Count == 1) && (xpi.MoveNext())) { XmlDocument dbxConfiguration = new XmlDocument(); dbxConfiguration.LoadXml(xpi.Current.OuterXml); IVfxFixDatabase database = VfxFixDatabaseFactory.Create(services, dbxConfiguration); this._localServices.AddService(typeof(IVfxFixDatabase), database); } }