private unsafe bool VerifyLoginAck(MessageFIXT1_1 message) { var packetFIX = message; if ("A" == packetFIX.MessageType && "FIX.4.2" == packetFIX.Version && "LIME" == packetFIX.Sender && UserName == packetFIX.Target && "0" == packetFIX.Encryption) { return(true); } else { var textMessage = new StringBuilder(); textMessage.AppendLine("Invalid login response:"); textMessage.AppendLine(" message type = " + packetFIX.MessageType); textMessage.AppendLine(" version = " + packetFIX.Version); textMessage.AppendLine(" sender = " + packetFIX.Sender); textMessage.AppendLine(" target = " + packetFIX.Target); textMessage.AppendLine(" encryption = " + packetFIX.Encryption); textMessage.AppendLine(" sequence = " + packetFIX.Sequence); textMessage.AppendLine(" heartbeat interval = " + packetFIX.HeartBeatInterval); textMessage.AppendLine(packetFIX.ToString()); log.Error(textMessage.ToString()); return(false); } }
protected override void HandleUnexpectedLogout(MessageFIXT1_1 message) { bool handled = false; var message42 = (MessageFIX4_2)message; if (message42.Text != null) { // If our sequences numbers don't match, Lime sends a logout with a message // telling us what we should be at. So if we can, we just use that when we reconnect. if (message42.Text.StartsWith("MsgSeqNum too low")) { var match = Regex.Match(message42.Text, "expecting (\\d+)"); int newSequenceNumber = 0; if (match.Success && int.TryParse(match.Groups[1].Value, out newSequenceNumber) && newSequenceNumber >= OrderStore.LocalSequence) { log.Error(message42.Text); OrderStore.SetSequences(OrderStore.RemoteSequence, newSequenceNumber); Socket.Dispose(); handled = true; RetryStart = 2; ignoreRetryDelay = true; } } else { base.HandleUnexpectedLogout(message); throw new LimeException(string.Format("Lime logged out with error '{0}'", message42.Text)); } } if (!handled) { base.HandleUnexpectedLogout(message); } }
protected override void SetupFixFactory(MessageFIXT1_1 packet) { // Lime doesn't reset want sequence numbers reset at startup. if (debug) { log.Debug("Setup Fix Factory"); } fixFactory = CreateFIXFactory(packet.Sequence, packet.Target, packet.Sender); RemoteSequence = packet.Sequence; }
protected override bool HandleLogon(MessageFIXT1_1 message) { if (ConnectionStatus != Status.PendingLogin) { throw new InvalidOperationException("Attempt logon when in " + ConnectionStatus + " instead of expected " + Status.PendingLogin); } if (VerifyLoginAck(message)) { RetryStart = 30; return(true); } else { RegenerateSocket(); return(false); } }
protected override void RemoveTickSync(MessageFIXT1_1 textMessage) { var mbtMsg = (MessageFIX4_2)textMessage; if (SyncTicks.Enabled && mbtMsg.MessageType == "8") { switch (mbtMsg.OrderStatus) { case "E": case "6": case "0": { var symbolInfo = Factory.Symbol.LookupSymbol(mbtMsg.Symbol); var tickSync = SyncTicks.GetTickSync(symbolInfo.BinaryIdentifier); tickSync.RemovePhysicalOrder("offline"); } break; case "A": if (mbtMsg.ExecutionType == "D") { // Is it a Forex order? var symbolInfo = Factory.Symbol.LookupSymbol(mbtMsg.Symbol); var tickSync = SyncTicks.GetTickSync(symbolInfo.BinaryIdentifier); tickSync.RemovePhysicalOrder("offline"); } break; case "2": case "1": { var symbolInfo = Factory.Symbol.LookupSymbol(mbtMsg.Symbol); var tickSync = SyncTicks.GetTickSync(symbolInfo.BinaryIdentifier); tickSync.RemovePhysicalFill("offline"); } break; } } }