public void OnSessionLogout(IVfxFixAppSession session, FixMessage msg) { FixField fixSCID = msg.Header.GetField(49); FixField fixTCID = msg.Header.GetField(56); Console.WriteLine(string.Format("FIX CLIENT: {0} - LOGOUT.", fixSCID.Content)); }
public void OnSessionLogon(IVfxFixAppSession session, FixMessage msg) { FixField fixSCID = msg.Header.GetField(49); FixField fixTCID = msg.Header.GetField(56); Console.WriteLine(string.Format("FIX CLIENT: {0} - LOGON", fixSCID.Content)); System.Threading.ThreadPool.QueueUserWorkItem(HandleWork_SendMessages, session); }
/// <summary> /// The AddMessage method adds an instance of a FIX message /// to the database file that is associated with the specified /// session. The index file is updated to reflect the position /// in the database of the message that is being added. /// </summary> /// <param name="sessionId"> /// The session id of the session the message relates to. /// </param> /// <param name="msg"> /// The FIX message to be added to the database. /// </param> public void AddMessage(string sessionId, FixMessage msg) { // REC: Create the details instance for the task: TaskDetails_Add taskDetails = new TaskDetails_Add(sessionId, msg); // REC: Enqueue the task for asynchronous execution: _sequencer.Enqueue(AddMessage_Entrypoint, taskDetails); }
/// <summary> /// The OnSessionRxAppMessage callback is invoked by a session /// when it receives an application layer message from the peer /// session it's interacting with. /// </summary> /// <param name="session"> /// The IVfxFixSession implementation that is issuing the /// callback to the handler. /// </param> /// <param name="msg"> /// The application message that the session has received /// from its corresponding peer session. /// </param> public void OnSessionRxAppMessage(IVfxFixSession session, FixMessage msg) { if (_mapAppSessions.ContainsKey(session.InstanceId)) { IVfxFixAppSession appSession = _mapAppSessions[session.InstanceId]; _application.OnSessionRxAppMessage(appSession, msg); } }
/// <summary> /// The OnSessionLogon callback method is invoked by an /// instance of a session when it completes a logon with /// the peer system it's communicating with. /// </summary> /// <param name="session"> /// The IVfxFixSession implementation that is issuing /// the callback to the handler. /// </param> /// <param name="msg"> /// The FIX logon message (request or response) that was /// received from the peer session. /// </param> public void OnSessionLogon(IVfxFixSession session, FixMessage msg) { // REC: Forward the callback to the appropriate method // on the application's callback interface: if (_mapAppSessions.ContainsKey(session.InstanceId)) { IVfxFixAppSession appSession = _mapAppSessions[session.InstanceId]; _application.OnSessionLogon(appSession, msg); } }
private void PopulateMsgElements(string version, string msgType, FixMessage msg) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { FixDxCollection msgElements = null; foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { // REC: Retrieve the dictionary associated with // the version definition: FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); // REC: Attempt to retrieve the specified message // type from the dictionary: FixDxMessage dxMessage = dxInstance.GetMessageByType(msgType); if (dxMessage != null) { msgElements = dxInstance.Resolve(dxMessage.Elements); break; } } if (msgElements != 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 msgElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Content.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Content.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Content.SetOrdering(ordering); } } }
/// <summary> /// The OnSessionLogout callback is invoked by the underlying /// instance of a FIX session to notify the service that the /// session has logged out from the peer system. /// </summary> /// <param name="session"> /// The FIX session that is generating the callback. /// </param> /// <param name="msg"> /// The FIX logout message received from the peer. /// </param> public void OnSessionLogout(IVfxFixSession session, FixMessage msg) { lock (_synch) { // REC: The FIX session is no longer established. _fixEstablished = false; // REC: Forward the logout notification to the app: _fixApplication.OnSessionLogout(_appSession, msg); } }
/// <summary> /// The OnSessionLogon callback is invoked by the underlying /// instance of a FIX session to notify the service that the /// session has completed a FIX logon with the peer. /// </summary> /// <param name="session"> /// The FIX session that is generating the callback. /// </param> /// <param name="msg"> /// The FIX logon message received from the peer. /// </param> public void OnSessionLogon(IVfxFixSession session, FixMessage msg) { lock (_synch) { // REC: The FIX session has been established. _fixEstablished = true; // REC: Forward the logon notification to the app: _fixApplication.OnSessionLogon(_appSession, msg); } }
public void ToString() { var sessionId = new SessionIdentity("FIX.4.2", "EXECUTOR", "CLIENT1"); var target = new FixMessage(sessionId, 'A'); target.Header.Add(34, "1"); target.Header.Add(52, "20200925-11:05:13.797"); target.Add(98, "0"); target.Add(108, "30"); var str = target.ToString(); Assert.AreEqual("8=FIX.4.2\u00019=70\u000135=A\u000149=EXECUTOR\u000156=CLIENT1\u000134=1\u000152=20200925-11:05:13.797\u000198=0\u0001108=30\u000110=096\u0001", str); }
/// <summary> /// The HandleTxMessage method is invoked to inform the /// session that its owner needs to send a message to the /// peer system. The session will finalize the message, add /// it to the session database, and then return the message /// to its owner via the callback interface. Once the owner /// receives the callback, it can then transmit the message /// to the peer system. /// </summary> /// <param name="msg"> /// The FIX message that the session's owner wants to send /// to the peer session. /// </param> public void HandleTxMessage(FixMessage msg) { // REC: Populate the header elements for the outbound // message using the local assembler instance: _fixAssembler.PopulateHeader(_sxVersion, msg); // REC: Populate the trailer elements for the outbound // message using the local assembler instance: _fixAssembler.PopulateTrailer(_sxVersion, msg); // REC: Finalize the message and dispatch it back to // the session's owner for transmission to the peer: Dispatch_AppMessage(msg); }
/// <summary> /// create message for test request /// создать сообщение для тестового запроса /// </summary> /// <param name="reqId"></param> /// <param name="isTrading"></param> /// <returns></returns> public string TestRequestMsg(string reqId, bool isTrading) { var newMessage = new FixMessage(++_msgSeqNum, "1", isTrading, _settings); var logOnFields = new List <Field> { new Field((int)Tags.TestReqID, reqId) }; newMessage.AddBody(logOnFields); var res = newMessage.ToString(); return(res); }
/// <summary> /// The HandleSession_Logon method is invoked to handle /// a logon message that has been received from the peer /// session that this session is communicating with. /// </summary> /// <param name="msg"> /// The FIX logon message received from the peer. /// </param> private void HandleSession_Logon(FixMessage msg) { // REC: Ensure that we're in the appropriate state // to handle a logon message: if (_currentState == SessionStates.Session_Pending || _currentState == SessionStates.Session_Closed) { // REC: Retrieve the FIX SenderCompID of the peer // from the logon message: FixField fldSenderCompID = msg.Header.GetField(49); if (fldSenderCompID != null) { string rxSenderCompID = fldSenderCompID.Content; if (string.IsNullOrEmpty(rxSenderCompID)) { // HELP: Should the session send a reject message // in this case, given that the peer didn't send // its FIX SenderCompID, or should this throw an // argument exception? } // REC: Transition to the opened state: _currentState = SessionStates.Session_Opened; // REC: Notify the session's owner that the session // has received the logon response from the server: _handler.OnSessionLogon(this, msg); } else { // REC: Throw an exception since the session has not // yet been established and there will be no handler // at the application level that can deal with this: throw new ArgumentException("Logon message missing required field - SenderCompID."); } } else { // REC: Notify the session handler that an // administrative message has been received // from the peer session: _handler.OnSessionRxAdmMessage(this, msg); // REC: Throw an exception that indicates the // session is not in the appropriate state to // handle the received message: throw new InvalidOperationException("Session state invalid for received message."); } }
/// <summary> /// The OnSessionTxAppMessage callback is invoked by a session /// when it is ready to dispatch an application message to the /// peer session it's interacting with. /// </summary> /// <param name="session"> /// The IVfxFixSession implementation that is issuing the /// callback to the handler. /// </param> /// <param name="msg"> /// The application message that the session wants to have sent /// to its corresponding peer session. /// </param> public void OnSessionTxAppMessage(IVfxFixSession session, FixMessage msg) { if (_mapAppSessions.ContainsKey(session.InstanceId)) { IVfxFixAppSession appSession = _mapAppSessions[session.InstanceId]; _application.OnSessionTxAppMessage(appSession, msg); // REC: Locate the IPC session identifier of the IPC session // that is associated with the service that is generating the // event and use that to send the message to the peer: if (_mapFixToIpc.ContainsKey(session.InstanceId)) { string ipcIdentifier = _mapFixToIpc[session.InstanceId]; _endpoint.Send(ipcIdentifier, new VfxMsgBlock(msg.ToString())); } } }
public void Run() { Console.ReadLine(); Console.WriteLine("sending"); var msg = new FixMessage(_session.ID, 'D'); msg.Header.Add(52, DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss.fff")); msg.Add(60, DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss.fff")); msg.Add(1, "test"); msg.Add(11, 1); msg.Add(21, 1); msg.Add(54, 1); msg.Add(55, "APPL"); msg.Add(40, 1); _session.SendAsync(msg); Console.ReadLine(); }
public static FixMessage readTagValues(TcpClient client) { FixMessage ret = new FixMessage(); int tag; string value; while (true) { tag = ReadInt(client); if (tag < 1) { break; } value = ReadString(client); ret.Add(new TagValue(tag, value)); } return ret; }
private void HandleWork_SendMessages(object state) { int orderId = 1; IVfxFixAppSession session = state as IVfxFixAppSession; for (int i = 0; i != 5; i++) { FixMessage msg = new FixMessage(); msg.Header.SetField(new FixField(35, "8")); msg.Content.SetField(new FixField(37, orderId++.ToString())); msg.Content.SetField(new FixField(17, "5000")); msg.Content.SetField(new FixField(20, "0")); msg.Content.SetField(new FixField(150, "0")); msg.Content.SetField(new FixField(39, "0")); msg.Content.SetField(new FixField(55, "AAPL")); msg.Content.SetField(new FixField(54, "1")); msg.Content.SetField(new FixField(151, "3000")); msg.Content.SetField(new FixField(14, "0")); msg.Content.SetField(new FixField(6, "0")); FixGroup grpTest = new FixGroup(382, "2"); FixCollection grpInstance = new FixCollection(); grpInstance.AddField(new FixField(375, "foo")); grpInstance.AddField(new FixField(337, "bar")); grpTest.Instances.Add(grpInstance); grpTest.Instances.Add(grpInstance); msg.Content.AddGroup(grpTest); session.Send(msg); } if (session != null) { for (int i = 0; i != 10000; i++) { FixMessage message = new FixMessage(); message.Header.AddField(new FixField(35, "D")); session.Send(message); } } }
/// <summary> /// create a message for request status /// создать сообщение для запроса статуса ордера /// </summary> /// <param name="clOrdId">order number specified by the user when creating/номер ордера заданный пользователем при создании</param> /// <param name="side">order side/направление ордера</param> /// <param name="securityId">instrument id/id инструмента</param> public string OrderStatusRequestMsg(string clOrdId, string securityId, string side) { var newMessage = new FixMessage(++_msgSeqNum, "H", true, _settings); var newOrder = new List <Field> { new Field((int)Tags.ClOrdID, clOrdId), new Field((int)Tags.SecurityID, securityId), new Field((int)Tags.SecurityIDSource, "8"), new Field((int)Tags.Side, side) }; newMessage.AddBody(newOrder); var res = newMessage.ToString(); return(res); }
/// <summary> /// The HandleSession_Heartbeat method is invoked to /// handle a heartbeat message from the peer. /// </summary> /// <param name="msg"> /// The FIX heartbeat message that was received. /// </param> private void HandleSession_Heartbeat(FixMessage msg) { if (_currentState == SessionStates.Session_Opened) { // REC: Dispatch the administrative message // to the session handler: _handler.OnSessionRxAdmMessage(this, msg); } else { // REC: Dispatch the administrative message // to the session handler: _handler.OnSessionRxAdmMessage(this, msg); // REC: Throw the invalid operation exception // since the session cannot handle the message: throw new InvalidOperationException("Session state invalid for received message."); } }
/// <summary> /// create message for cancelling order /// создать сообщение для отмены ордера /// </summary> public string OrderCancelRequestMsg(string origClOrdId, string clOrdId, string securityId) { var newMessage = new FixMessage(++_msgSeqNum, "F", true, _settings); var newOrder = new List <Field> { new Field((int)Tags.OrigClOrdID, clOrdId), new Field((int)Tags.ClOrdID, origClOrdId), new Field((int)Tags.SecurityID, securityId), new Field((int)Tags.SecurityIDSource, "8"), new Field((int)Tags.TransactTime, DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss")) }; newMessage.AddBody(newOrder); var res = newMessage.ToString(); return(res); }
/// <summary> /// message for entering /// сообщение для входа /// </summary> /// <param name="isTrading">true - if the entrance to the trading session, false for market data / true - если вход в торговую сессию, false для market data</param> /// <param name="heartbeatInterval"></param> /// <returns>сообщение в формате fix</returns> public string LogOnMsg(bool isTrading, int heartbeatInterval) { var newMessage = new FixMessage(++_msgSeqNum, "A", isTrading, _settings); var logOnFields = new List <Field> { new Field((int)Tags.EncryptMethod, "0"), new Field((int)Tags.HeartBtInt, heartbeatInterval.ToString()), new Field((int)Tags.ResetSeqNumFlag, "Y"), new Field((int)Tags.Username, _settings.Username), new Field((int)Tags.Password, _settings.Password) }; newMessage.AddBody(logOnFields); var res = newMessage.ToString(); return(res); }
public void ReceviedFIXMessage(FixMessage fm) { if (fm.SecurityType == CashDefinition.SECURITY_CASH) { QuickFix.Message msg = QMessageBuilder.BuildDbMessage(fm.Message, fm.DbID, fm.TEBID, CashAppContext.ValidateMessage); if (CashAppContext != null && CashAppContext.App != null) { CashAppContext.App.Recieve(msg); } } else if (fm.SecurityType == CashDefinition.SECURITY_FUTURE || fm.SecurityType == CashDefinition.SECURITY_OPTION) { QuickFix.Message msg = QMessageBuilder.BuildDbMessage(fm.Message, fm.DbID, fm.TEBID, VIOPAppContext.ValidateMessage); if (VIOPAppContext != null && VIOPAppContext.App != null) { VIOPAppContext.App.Recieve(msg); } } }
public string TradeCaptureReportRequestMsg(string tradeRequestId, string tradeRequestType, string subscriptionRequestType, DateTime starTime, DateTime endTime) { var newMessage = new FixMessage(++_msgSeqNum, "AD", true, _settings); var newOrder = new List <Field> { new Field((int)Tags.TradeRequestID, tradeRequestId), new Field((int)Tags.TradeRequestType, tradeRequestType), new Field((int)Tags.SubscriptionRequestType, subscriptionRequestType), new Field((int)Tags.NoDates, "2"), new Field((int)Tags.TransactTime, starTime.ToString("yyyyMMdd-HH:mm:ss")), new Field((int)Tags.TransactTime, endTime.ToString("yyyyMMdd-HH:mm:ss")) }; newMessage.AddBody(newOrder); var res = newMessage.ToString(); return(res); }
/// <summary> /// The HandleShutdown_Entrypoint method is the asynchronous /// entry point for the session's shutdown logic. /// </summary> /// <param name="state"> /// Ignored parameter - required for the method to match the /// needed signature for use with the sequencer. /// </param> private void HandleShutdown_Entrypoint(object state) { // REC: If the session is currently logged on, we need // to dispatch a logout message to the peer: if (_currentState == SessionStates.Session_Opened) { // REC: Transition to the closing state: _currentState = SessionStates.Session_Closing; FixMessage msgResponse = _fixAssembler.CreateMessage(_sxVersion, _axVersion, "5"); if (msgResponse != null) { // REC: Dispatch the logout message to the // peer session. The shutdown process will // complete when the peer responds with an // acknowledgment of the logout: Dispatch_AdmMessage(msgResponse); } } else if (_currentState == SessionStates.Session_Pending) { // REC: Transition to the shutdown state: _currentState = SessionStates.Session_Shutdown; // REC: Dispatch the shutdown notification // to the session's handler: _handler.OnSessionClosed(this); } else if (_currentState == SessionStates.Session_Closed) { // REC: Transition to the shutdown state: _currentState = SessionStates.Session_Shutdown; // REC: Release the session record: _fixDatabase.ReleaseSession(_sessionId, _sessionRecord); // REC: Dispatch the shutdown notification // to the session's handler: _handler.OnSessionClosed(this); } }
/// <summary> /// The Finalize method calculates the values for /// common session layer fields and assigns those /// values to their respective fields. /// </summary> /// <param name="msg"> /// The FIX message to be finalized. /// </param> public static void Finalize(FixMessage msg) { // REC: Calculate sending time and add it to the message: string strTimeStamp = DateTime.UtcNow.ToString("yyyyMMdd-HH:mm:ss.fff"); FixField fldSendingTime = msg.Header.GetField(52); if (fldSendingTime != null) { fldSendingTime.Content = strTimeStamp; } else { msg.Header.AddField(new FixField(52, strTimeStamp)); } // REC: Calculate the body length and add it to the message: int fixBodyLength = FixCalculator.GetBodyLength(msg); FixField fldBodyLength = msg.Header.GetField(9); if (fldBodyLength != null) { fldBodyLength.Content = fixBodyLength.ToString(); } else { msg.Header.AddField(new FixField(9, fixBodyLength.ToString())); } // REC: Calculate the checksum and add it to the message: string strChecksum = string.Format("{0:000}", FixCalculator.GetChecksum(msg) % 256); FixField fldChecksum = msg.Trailer.GetField(10); if (fldChecksum != null) { fldChecksum.Content = strChecksum; } else { msg.Trailer.AddField(new FixField(10, strChecksum)); } }
public void OnMessage(FixMessage msg) { Console.WriteLine(">" + msg.ToString()); var msgType = msg.Header[Tags.MsgType] as FixField <char>; switch (msgType.Value) { case 'D': var accept = new FixMessage(_session.RevertID, '8'); accept.Header.Add(52, DateTime.UtcNow.ToString(FixSettings.DateTimeFormat)); accept.Add(6, 0); accept.Add(14, 0); accept.Add(17, _execId++); accept.Add(37, _orderId++); accept.Add(msg[11]); accept.Add(39, 2); accept.Add(msg[54]); accept.Add(msg[55]); accept.Add(150, 0); accept.Add(151, 0); _session.SendAsync(accept); return; } }
/// <summary> /// The HandleSession_Message method is invoked to handle /// an incoming message that needs to be routed up to the /// session's application level message handler. /// </summary> /// <param name="msg"></param> private void HandleSession_Message(FixMessage msg) { // REC: Dispatch the message to the session's event // callback handler and let it process the message: _handler.OnSessionRxAppMessage(this, msg); }
/// <summary> /// The PopulateHeader method populates all of the header /// elements in the specified message with the elements that /// are specified in a specific FIX version, using the values /// that have been set for those fields in the assembler. The /// method will replace the sort ordering for the target with /// the sort ordering that is found in the dictionary. /// </summary> /// <param name="sxVersion"> /// The name of the session layer version that the elements /// for the message trailer will be retrieved from. /// </param> /// <param name="msg"> /// The FIX message instance that is to be populated. /// </param> public void PopulateHeader(string sxVersion, FixMessage msg) { PopulateHdrElements(sxVersion, msg); }
/// <summary> /// The PopulateTrailer method populates all of the trailer /// elements in the specified message with the elements that /// are specified in a specific FIX version, using the values /// that have been set for those fields in the assembler. The /// method will replace the sort ordering for the target with /// the sort ordering that is found in the dictionary. /// </summary> /// <param name="sxVersion"> /// The name of the session layer version that the elements /// for the message trailer will be retrieved from. /// </param> /// <param name="msg"> /// The FIX message instance that is to be populated. /// </param> public void PopulateTrailer(string sxVersion, FixMessage msg) { PopulateTrlElements(sxVersion, msg); }
private void PopulateTrlElements(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 trlElements = dxEntry.Resolve(dxEntry.Trailer); if (trlElements != 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 trlElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Trailer.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Trailer.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Trailer.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); } }
/// <summary> /// The HandleSession_Resend method is invoked in response /// to the session receiving a FIX resend request from the /// peer system that it's interacting with. /// </summary> /// <param name="msg"> /// The FIX resend message received from the peer. /// </param> private void HandleSession_Resend(FixMessage msg) { }
public void OnSessionRxAdmMessage(IVfxFixAppSession session, FixMessage msg) { FixField fixSCID = msg.Header.GetField(49); Console.WriteLine(string.Format("FIX CLIENT: {0} SENT: {1}", fixSCID.Content, msg.ToString())); }
/// <summary> /// The HandleSession_Logon method is invoked to handle /// a logon message that has been received from the peer /// session that this session is communicating with. /// </summary> /// <param name="msg"> /// The FIX logon message received from the peer. /// </param> private void HandleSession_Logon(FixMessage msg) { // REC: Ensure that we're in the appropriate state // to handle a logon message: if (_currentState == SessionStates.Session_Pending || _currentState == SessionStates.Session_Closed) { // REC: Retrieve the FIX SenderCompID of the peer // from the logon message: FixField fldSenderCompID = msg.Header.GetField(49); if (fldSenderCompID != null) { // REC: The SenderCompID from the peer becomes the // session's TargetCompID for outgoing messages: _fixTargetCompID = fldSenderCompID.Content; // REC: Now that the FIX SenderCompID of the peer // session is known, it is used to construct the // identifier for the session - used to retrieve // the session's details from the database: _sessionId = string.Format("{0}-{1}", _fixSenderCompID, _fixTargetCompID); // REC: Attempt to retrieve the session details // from the session database: if (_fixDatabase != null) { // REC: Note that once a session record is acquired // from the database, it must be released when it is // no longer needed by the session instance... _sessionRecord = _fixDatabase.AcquireSession(_sessionId); if (this._resetSequence == true) { _sessionRecord.RxSequence = 1; _sessionRecord.TxSequence = 1; } } // REC: Register the peer session's SenderCompID as // the TargetCompID for outgoing messages: _fixAssembler.SetField(new FixField(56, _fixTargetCompID)); // REC: Assemble the response message: FixMessage response = _fixAssembler.CreateMessage(_sxVersion, _axVersion, "A"); // REC: Handle the sequence number reset flag // if it is present in the logon message: FixField fieldReset = msg.GetField(141); if (fieldReset != null) { response.AddField(new FixField(141, "Y")); } // REC: Transition to the opened state: _currentState = SessionStates.Session_Opened; // REC: Notify the session's owner that the peer // session has sent the logon request: _handler.OnSessionLogon(this, msg); // REC: Dispatch the administrative message out // to the session's owner: Dispatch_AdmMessage(response); } else { // REC: Throw an exception since the session has not // yet been established and there will be no handler // at the application level that can deal with this: throw new ArgumentException("Logon message missing required field - SenderCompID."); } } else { // REC: Notify the session handler that an // administrative message has been received // from the peer session: _handler.OnSessionRxAdmMessage(this, msg); // REC: Throw an exception that indicates the // session is not in the appropriate state to // handle the received message: //throw new InvalidOperationException("Session state invalid for received message."); } }
/// <summary> /// The OnSessionRxAppMessage callback is invoked by a session /// when it receives an application layer message from the peer /// session it's interacting with. /// </summary> /// <param name="session"> /// The IVfxFixSession implementation that is issuing the /// callback to the handler. /// </param> /// <param name="msg"> /// The application message that the session has received /// from its corresponding peer session. /// </param> public void OnSessionRxAppMessage(IVfxFixSession session, FixMessage msg) { // REC: Forward the app message to the application: _fixApplication.OnSessionRxAppMessage(_appSession, msg); }
/// <summary> /// The HandleSession_TestRequest method is invoked to /// handle a test request that has been received from the /// peer that the session is interacting with. /// </summary> /// <param name="msg"> /// The FIX test request received from the peer. /// </param> private void HandleSession_TestRequest(FixMessage msg) { if (_currentState == SessionStates.Session_Opened) { // REC: Dispatch the administrative message to the // session's callback handler: _handler.OnSessionRxAdmMessage(this, msg); // REC: Construct a response message to the test // request and dispatch it to the peer: FixMessage msgResponse = _fixAssembler.CreateMessage(_sxVersion, _axVersion, "0"); if (msgResponse != null) { // REC: Retrieve the test request token from // the incoming request and assign it to the // outbound response message: FixField fldTestReqID = msg.GetField(112); if (fldTestReqID != null) { if (!string.IsNullOrEmpty(fldTestReqID.Content)) { msgResponse.AddField(new FixField(112, fldTestReqID.Content)); } } Dispatch_AdmMessage(msgResponse); } } else { } }
/// <summary> /// The CreateMessage method creates a new instance of /// a specific FIX message in accordance with the message /// definition in the dictionaries associated with the /// specified FIX application layer version. The message /// that is created by this implementation of the method /// will also include a populated header and trailer that /// conforms to the header and trailer definition found in /// the specified session layer FIX version. /// </summary> /// <param name="sxVersion"> /// The session layer version of the FIX protocol that will /// be used to locate message definitions for the message that /// is to be created. /// </param> /// <param name="axVersion"> /// The application layer version of the FIX protocol that /// will be used to locate the message definition for the /// message that is to be created. /// </param> /// <param name="msgType"> /// The FIX message type of the message to create. /// </param> /// <returns> /// The resulting instance of a FIX message. /// </returns> public FixMessage CreateMessage(string sxVersion, string axVersion, string msgType) { FixMessage result = new FixMessage(); // REC: Determine if the MsgType field has already // been defined and maintain a reference so that it // can be restored after this is done: FixField fldMsgType = GetField(35); // REC: Assign the specified MsgType to the internal // field map so that it gets substituted: SetField(new FixField(35, msgType)); PopulateHdrElements(sxVersion, result); PopulateMsgElements(axVersion, msgType, result); PopulateTrlElements(sxVersion, result); // REC: Restore the previous value for the // message type, if one was present: if (fldMsgType != null) { SetField(fldMsgType); } else { // REC: The MsgType field was not present before // this call was made, so remove it: RemoveField(35); } return result; }
/// <summary> /// The HandleSession_Heartbeat method is invoked to /// handle a heartbeat message from the peer. /// </summary> /// <param name="msg"> /// The FIX heartbeat message that was received. /// </param> private void HandleSession_Heartbeat(FixMessage msg) { if (_currentState == SessionStates.Session_Opened) { // REC: Reset the heartbeat timestamp: _rxLastHeartbtTicks = DateTime.Now.Ticks; // REC: Dispatch the administrative message // to the session handler: _handler.OnSessionRxAdmMessage(this, msg); } else { // REC: Dispatch the administrative message // to the session handler: _handler.OnSessionRxAdmMessage(this, msg); // REC: Throw the invalid operation exception // since the session cannot handle the message: throw new InvalidOperationException("Session state invalid for received message."); } }
/// <summary> /// The CreateMessage method creates a new instance of /// a specific FIX message in accordance with the message /// definition in the dictionaries associated with the /// specified FIX application layer version. The message /// that is created by this implementation of the method /// will not contain a populated header or trailer. /// </summary> /// <param name="axVersion"> /// The application layer version of the FIX protocol that /// will be used to locate the message definition for the /// message that is to be created. /// </param> /// <param name="msgType"> /// The FIX message type of the message to create. /// </param> /// <returns></returns> public FixMessage CreateMessage(string axVersion, string msgType) { FixMessage result = new FixMessage(); PopulateMsgElements(axVersion, msgType, result); return result; }
/// <summary> /// The HandleSession_Logout method is invoked to handle /// a logout message that has been received from the peer /// session that the session is interacting with. /// </summary> /// <param name="msg"> /// The FIX logout message that was received. /// </param> private void HandleSession_Logout(FixMessage msg) { // REC: If the session is already in the closing // state, then this is the acknowledgement by the // peer session that it has received the logout: if (_currentState == SessionStates.Session_Closing) { // REC: Transition to the shutdown state: _currentState = SessionStates.Session_Shutdown; // REC: Notify the session handler that the // administrative message has been received // from the peer session: _handler.OnSessionRxAdmMessage(this, msg); // REC: Release the session record from the // database so that it can be used again: _fixDatabase.ReleaseSession(_sessionId, _sessionRecord); // REC: Dispatch the shutdown notification // to the session handler: _handler.OnSessionClosed(this); } else if (_currentState == SessionStates.Session_Opened) { // REC: Transition to the closing state: _currentState = SessionStates.Session_Closing; // REC: Notify the session handler that the // administrative message has been received // from the peer session: _handler.OnSessionRxAdmMessage(this, msg); // REC: Release the session record from the // database so that it can be used again: _fixDatabase.ReleaseSession(_sessionId, _sessionRecord); // REC: Dispatch a logout response to the peer // session to acknowledge the shutdown: FixMessage msgResponse = _fixAssembler.CreateMessage(_sxVersion, _axVersion, "5"); if (msgResponse != null) { Dispatch_AdmMessage(msgResponse); } // REC: Transition to the closed state: _currentState = SessionStates.Session_Closed; // REC: Notify the session handler that // the session is logged out: _handler.OnSessionLogout(this, msg); } else { // REC: Notify the session handler that an // administrative message has been received: _handler.OnSessionRxAdmMessage(this, msg); // REC: Throw an exception that indicates the // message was received in an invalid state: throw new InvalidOperationException("Session state invalid for received message."); } }
private void PopulateTrlElements(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 trlElements = dxEntry.Resolve(dxEntry.Trailer); if (trlElements != 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 trlElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Trailer.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Trailer.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Trailer.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 Enqueue(FixMessage fixMessage) { base.Enqueue(fixMessage); }
private void PopulateMsgElements(string version, string msgType, FixMessage msg) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { FixDxCollection msgElements = null; foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { // REC: Retrieve the dictionary associated with // the version definition: FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); // REC: Attempt to retrieve the specified message // type from the dictionary: FixDxMessage dxMessage = dxInstance.GetMessageByType(msgType); if (dxMessage != null) { msgElements = dxInstance.Resolve(dxMessage.Elements); break; } } if (msgElements != 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 msgElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Content.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Content.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Content.SetOrdering(ordering); } } }
public void OnMessage(FixMessage msg) { Console.WriteLine(">" + msg.ToString()); }
/// <summary> /// heartbeat message /// сообщение пулься /// </summary> public string HeartbeatMsg(bool isTrading) { var newMessage = new FixMessage(++_msgSeqNum, "0", isTrading, _settings); return(newMessage.ToString()); }
/// <summary> /// The Dispatch_AppMessage method is invoked by the /// session to finalize an outbound application layer /// message and return it to the session's owner for /// transmission to the peer system. /// </summary> /// <param name="msg"> /// The FIX message to be finalized and dispatched. /// </param> private void Dispatch_AppMessage(FixMessage msg) { // REC: Adjust the tick counter to reflect the // time that the more recent message was sent: this._lastTxTicks = DateTime.Now.Ticks; // REC: Assign the FIX BeginString to the message: msg.Header.SetField(new FixField(8, _fixBeginString)); // REC: Assign the outbound sequence number to the // message based on the persisted session record: msg.Header.SetField(new FixField(34, _sessionRecord.TxSequence.ToString())); _sessionRecord.TxSequence++; // REC: Finalize the message so that its checksum and // related fields are set correctly: FixFinalizer.Finalize(msg); // REC: Insert the outbound message into the session // database so that it can be recovered if there is a // resend request from the peer session: _fixDatabase.AddMessage(_sessionId, msg); // REC: Dispatch the finalized message to the owner // of the session so it can be sent to the peer: _handler.OnSessionTxAppMessage(this, msg); }
/// <summary> /// The HandleSession_Logout method is invoked to handle /// a logout message that has been received from the peer /// session that the session is interacting with. /// </summary> /// <param name="msg"> /// The FIX logout message that was received. /// </param> private void HandleSession_Logout(FixMessage msg) { // REC: If the session is already in the closing // state, then this is the acknowledgement by the // peer session that it has received the logout: if (_currentState == SessionStates.Session_Closing) { // REC: Transition to the shutdown state: _currentState = SessionStates.Session_Shutdown; // REC: Notify the session handler that the // administrative message has been received // from the peer session: _handler.OnSessionRxAdmMessage(this, msg); // REC: Release the session record from the // database so that it can be used again: _fixDatabase.ReleaseSession(_sessionId, _sessionRecord); // REC: Dispatch the shutdown notification // to the session handler: _handler.OnSessionClosed(this); } else if (_currentState == SessionStates.Session_Opened) { // REC: Transition to the closing state: _currentState = SessionStates.Session_Closing; // REC: Notify the session handler that the // administrative message has been received // from the peer session: _handler.OnSessionRxAdmMessage(this, msg); // REC: Dispatch a logout response to the peer // session to acknowledge the shutdown: FixMessage msgResponse = _fixAssembler.CreateMessage(_sxVersion, _axVersion, "5"); if (msgResponse != null) { Dispatch_AdmMessage(msgResponse); } // REC: Transition to the closed state: _currentState = SessionStates.Session_Closed; // REC: Release the session record from the // database so that it can be used again: _fixDatabase.ReleaseSession(_sessionId, _sessionRecord); // REC: Notify the session handler that // the session is logged out: _handler.OnSessionLogout(this, msg); } else { // REC: Notify the session handler that an // administrative message has been received: _handler.OnSessionRxAdmMessage(this, msg); // REC: Throw an exception that indicates the // message was received in an invalid state: throw new InvalidOperationException("Session state invalid for received message."); } }
/// <summary> /// The GetChecksum method calculates the checksum for /// an instance of a FIX message. /// </summary> /// <param name="msg"> /// The FIX message to analyze. /// </param> /// <returns> /// The FIX protocol checksum of the message. /// </returns> public static int GetChecksum(FixMessage msg) { int result = 0; // REC: Process the header elements: foreach (IFixElement hdrElement in msg.Header) { result += CalculateSum(hdrElement.Tag.ToString()); result += 0x3D; result += CalculateSum(hdrElement.Content); result += 0x01; FixGroup group = hdrElement as FixGroup; if (group != null) { foreach (FixCollection instance in group.Instances) { result += CalculateSum(instance); } } } // REC: Process the message body: foreach (IFixElement msgElement in msg.Content) { result += CalculateSum(msgElement.Tag.ToString()); result += 0x3D; result += CalculateSum(msgElement.Content); result += 0x01; FixGroup group = msgElement as FixGroup; if (group != null) { foreach (FixCollection instance in group.Instances) { result += CalculateSum(instance); } } } // REC: Process the message trailer: foreach (IFixElement trlElement in msg.Trailer) { if (trlElement.Tag == 10) { break; } result += CalculateSum(trlElement.Tag.ToString()); result += 0x3D; result += CalculateSum(trlElement.Content); result += 0x01; FixGroup group = trlElement as FixGroup; if (group != null) { foreach (FixCollection instance in group.Instances) { result += CalculateSum(instance); } } } return result; }
/// <summary> /// The GetBodyLength method calculates the appropriate /// value for the FIX BodyLength field of the specified /// message, in accordance with the FIX Protocol. /// </summary> /// <param name="msg"> /// The message that the BodyLength value is to be /// calculated from. /// </param> /// <returns> /// The body length of the message, calculated according /// to the method specified in the FIX protocol. /// </returns> public static int GetBodyLength(FixMessage msg) { int result = 0; // REC: Calculate the combined length of all // elements in the header of the message: bool lengthFound = false; foreach (IFixElement element in msg.Header) { if (lengthFound == true) { result += element.Tag.ToString().Length; result += 1; result += element.Content.Length; result += 1; FixGroup group = element as FixGroup; if (group != null) { foreach (FixCollection instance in group.Instances) { result += CalculateLength(instance); } } } else { if (element.Tag == 9) { lengthFound = true; } } } // REC: Calculate the combined length of all // the body elements in the message: foreach (IFixElement element in msg.Content) { result += element.Tag.ToString().Length; result += 1; result += element.Content.Length; result += 1; FixGroup group = element as FixGroup; if (group != null) { foreach (FixCollection instance in group.Instances) { result += CalculateLength(instance); } } } // REC: Calculate the combined length of all // elements in the trailer of the message: foreach (IFixElement element in msg.Trailer) { // REC: Terminate when the checksum field // is encountered in the trailer: if (element.Tag == 10) { break; } result += element.Tag.ToString().Length; result += 1; result += element.Content.Length; result += 1; FixGroup group = element as FixGroup; if (group != null) { foreach (FixCollection instance in group.Instances) { result += CalculateLength(instance); } } } return result; }
public void OnSessionTxAppMessage(IVfxFixAppSession session, FixMessage msg) { }
/// <summary> /// The OnSessionTxAppMessage callback is invoked by a session /// when it is ready to dispatch an application message to the /// peer session it's interacting with. /// </summary> /// <param name="session"> /// The IVfxFixSession implementation that is issuing the /// callback to the handler. /// </param> /// <param name="msg"> /// The application message that the session wants to have sent /// to its corresponding peer session. /// </param> public void OnSessionTxAppMessage(IVfxFixSession session, FixMessage msg) { // REC: Forward the app message to the application: _fixApplication.OnSessionTxAppMessage(_appSession, msg); // REC: Send the app message to the peer system: _ipcEndpoint.Send(null, new VfxMsgBlock(msg.ToString())); }