Beispiel #1
0
        /// <summary>
        /// Validates a FixMessage. Returns empty string if valid, otherwise a message indicating the validation errors.
        /// </summary>
        /// <param name="fixMessage"></param>
        /// <returns>string</returns>
        public static string ValidateFixMessage(FixMessage fixMessage)
        {
            if (fixMessage == null)
            {
                return("Fix Message Invalid.");
            }

            string validationMsg = string.Empty;

            try
            {
                if (!fixMessage.Contains(Tag.MsgType))
                {
                    validationMsg += "MsgType";
                }
                if (!fixMessage.Contains(Tag.BeginString))
                {
                    validationMsg += ", BeginString";
                }
                if (!fixMessage.Contains(Tag.SenderCompID))
                {
                    validationMsg += ", SenderCompID";
                }
                if (!fixMessage.Contains(Tag.TargetCompID))
                {
                    validationMsg += ", TargetCompID";
                }

                if (validationMsg != string.Empty)
                {
                    validationMsg = string.Format("Missing fields: {0}.", validationMsg);
                }
            }
            catch (Exception ex)
            {
                validationMsg = string.Format("ValidateFixMessage: Error: {0}", ex.Message);
            }

            return(validationMsg);
        }
Beispiel #2
0
 public void Enqueue(FixMessage fixMessage)
 {
     base.Enqueue(fixMessage);
 }
Beispiel #3
0
        /// <summary>
        /// Adds an array of fields to the FixMessage.
        /// </summary>
        /// <param name="fields">An array of fields.</param>
        private void AddFieldArray(string[] fields)
        {
            // This local is used for repeating groups (see below.)
            StringCollection groupFields = new StringCollection();

            // Add each field after parse the values into a "Tag=Value" pair.
            foreach (string field in fields)
            {
                // The 'Split' method has a bothersome habit of leaving a null entry when a token delimiter ends up a the end
                // of the string.  This will quickly filter out those byproducts of the 'Split'.
                if (field == string.Empty)
                {
                    continue;
                }

                // Break the field up into the 'Tag' and 'Value' fields, parse them and add them to the hash table.
                string[] values = field.Split('=');
                if (values.Length > 1)
                {
                    try
                    {
                        //tagNumber
                        Tag tag = MarkThree.TagConverter.ConvertFrom(values[0]);

                        string stringValue = values[1];

                        // Handle repeating group fields here.
                        // Per the FIX spec:
                        //  "Fields within repeating data groups must be specified in the order that the fields are
                        //  specified in the message definition within the FIX specification document. The NoXXX field,
                        //  where XXX is the field being counted, specifies the number of repeating group instances and
                        //  must immediately precede the repeating group contents."
                        // Generally:
                        //   1. record the number of repeating group instances for a group when the NoXXX field occurs.
                        //   2. when each field in the group is read, save it in the groupFields array, unless it the last field.
                        //   3. when the last field of the group occurs, add a group entry to the group object.
                        // Order is important (See note from FIX spec above.) groupFields index 0 is the first field of the group, 1 is the second, etc.
                        // The xxxxGroup object (derived from class RepeatingGroup) holds the all of the repeating groups relating to "xxxx".
                        // Each repeating group in xxxxGroup is called an Entry.
                        // The groupFields array is temp space to hold the group fields as they are read from the FIX string.
                        switch (tag)
                        {
                        // IOIQualifiers.
                        // There is only one field (IOIQualifier) in each group, so groupFields is not used.
                        case Tag.NoIOIQualifiers:
                            // This field indicates the start of a set of repeating groups.
                            // But for FIX 4.0, only one IOIQualifier is allowed and this field is not used.
                            // So don't create the group object here, create it when the first qualifier is encountered.
                            // See IOIQualifier below.
                            break;

                        case Tag.IOIQualifier:
                            if (!this.ContainsKey(Tag.IoiQualifierGroup))
                            {
                                // if there is not yet an IoiQualifierGroup, create the group object to hold the repeating groups.
                                this[Tag.IoiQualifierGroup] = new IoiQualifierGroup();
                            }
                            // get the group object created previously.
                            IoiQualifierGroup ioiQualifierGroup = (IoiQualifierGroup)this[Tag.IoiQualifierGroup];
                            // IOIQualifier is the only field in this group, so add the group to the IoiQualifierGroup object.
                            // IOIQualifier is not a string in FixMessage, so it needs to be parsed into its correct type.
                            ioiQualifierGroup.Add((IOIQualifier)FixMessage.Parse(tag, stringValue));
                            break;

                        // RoutingIDs. (Valid in FIX 4.2 only.)
                        // There are 2 fields in each group here, so save the first one in the groupFields array.
                        // (It could just be saved in a string variable, but the array is more general. A group can have more than 2 fields.)
                        // For example:
                        // The following FIX string describes three repeating groups for Routing (215=3), with the first group having
                        // two fields: RoutingType=3 (216=3), and RoutingID=RTEID1 (217=RTEID1). Similarly for groups 2 and 3.
                        // 215=3|216=3|217=RTEID1|216=3|217=RTEID2|216=3|217=RTEID3|
                        case Tag.NoRoutingIDs:
                            // This field indicates the start of a set of repeating groups.
                            // Create the group object to hold the repeating groups.
                            this[Tag.RoutingGroup] = new RoutingGroup();
                            break;

                        case Tag.RoutingType:
                            // Save the RoutingType string in the groupFields collection.
                            groupFields.Add(stringValue);
                            break;

                        case Tag.RoutingID:
                            // RoutingID is the last field in this group, so add the group to the RoutingGroup object.
                            if (this.Contains(Tag.RoutingGroup))
                            {
                                // get the group object created above.
                                RoutingGroup routingGroup = (RoutingGroup)this[Tag.RoutingGroup];
                                if (groupFields.Count > 0)
                                {
                                    // Add the current group fields to the group object.
                                    // The first (and in this case only) item in the groupFields array is RoutingType.
                                    // RoutingType combined with the RoutingID is a complete group.
                                    // RoutingID is a string in FixMessage, so it doesn't need to be parsed.
                                    // RoutingType is not a string in FixMessage, so it needs to be parsed into its correct type.
                                    RoutingType routingType = (RoutingType)FixMessage.Parse(Tag.RoutingType, groupFields[0]);
                                    routingGroup.Add(routingType, stringValue);

                                    // once the group has been added, clear out the temp array for the next group.
                                    groupFields.Clear();
                                }
                            }
                            break;

                        // Regular processing of (non-repeating) FIX fields.
                        default:
                            this[tag] = FixMessage.Parse(tag, stringValue);
                            break;
                        }
                    }
                    catch
                    {
                        string SenderComp = this.Contains(Tag.SenderCompID) ? this.SenderCompID : string.Empty;
                        string TargetComp = this.Contains(Tag.TargetCompID) ? this.TargetCompID : string.Empty;
                        MarkThree.EventLog.Error("MsgSeqNum={0}, SenderCompID={1}, TargetCompID={2}: Can't parse FIX field {3}={4}. Field ignored.", this.MsgSeqNum, SenderComp, TargetComp, values[0], values[1]);
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Converts the tag number string to a Tag, uses
        /// the Parse method of the FixMessage class to convert
        /// the text value to the proper type, and adds the field.
        /// </summary>
        /// <param name="tagNumber"></param>
        /// <param name="stringValue"></param>
        public void AddField(string tagNumber, string stringValue)
        {
            Tag tag = MarkThree.TagConverter.ConvertFrom(tagNumber);

            this[tag] = FixMessage.Parse(tag, stringValue);
        }