Thank you for you very complete response! <br><br>A few questions...<br><br>There's been a lot of talk at my job about using FIX to standardize the application infrastructure (logging, some kinds of IPC, etc. ), in which case many of these tags would likely be in the range of FIX tags that are reserved for vendor communications and are thus undocumented/undefined.&nbsp; For a case such as this, in your experience, is there any simple (yet robust) way respond to tags that have not been encountered before?&nbsp; That is, do you think that such a parser might need a more complete grammar specification than a simple hash, or is FIX itself simple enough that certain default responses could be engineered for ranges of tags regardless of whether they already resided in a local specification hash?
<br><br><br><br>Thanks again, your insight has been very helpful,<br>Montgomery<br><br><br><div><span class="gmail_quote">On 12/2/06, <b class="gmail_sendername">Holzman, Benjamin</b> &lt;<a href="mailto:BHolzman@iseoptions.com">
BHolzman@iseoptions.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">&gt; I would have assumed that FIX is so large that any generic
<br>&gt; implementation of it is likely to be incomplete.<br><br>Yes and no, I think.&nbsp;&nbsp;My experience with FIX has been that the<br>application-level messages tend to be domain-specific, but the<br>protocol-level is quite stable.&nbsp;&nbsp;I have built FIX interfaces to allow
<br>order entry and market data for our parimutuel matching engine.&nbsp;&nbsp;I did<br>it using the quickfix open source FIX engine (actually C++ libraries) to<br>handle the protocol and wrote a minimal C++ bridge that shuttles FIX
<br>application messages back and forth to a perl process over a socket.<br><br>I then parse the FIX messages in perl with a custom FixMessage base<br>class, run all of my application logic there, creating FixMessage<br>objects as responses and then turn them back into a string to send back
<br>to the C++ bridge.&nbsp;&nbsp;I store the FIX messages as a hash mapping the fix<br>tag number to the value.&nbsp;&nbsp;I then have accessor methods named after the<br>mnemonic for each tag number.&nbsp;&nbsp;I actually just have a hash (%tagMapping)
<br>in my base class with the mapping and use an AUTOLOAD to create the<br>accessors on demand.&nbsp;&nbsp;Parsing the FIX message is as simple as this code:<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;sub fromString {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $string = shift;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my($class, %tags);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach my $field (split /\001/, $string) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my($tag, $value) = split /=/, $field, 2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($tag == $tagMapping{'MsgType'}) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class = $msgType_2_class{$value};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next if defined $isHeaderTag{$tag};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tags{$tag} = $value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $class-&gt;new(\%tags);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>I have sub-classes of FixMessage for each MsgType that I handle; the
<br>%msgType_2_class hash has the mapping.<br><br>Actually, there's an additional complication to handle repeating groups;<br>the value of a repeating group is an array ref with one element for each<br>instance of the group; because tag order in repeating groups matters,
<br>each instance is represented with an array consisting of tag<br>number/value pairs.&nbsp;&nbsp;Something like this: [ [ 42 =&gt; 'value', 165 =&gt;<br>'another value' ], [ 42 =&gt; 'value2', 165 =&gt; 'yet another' ], ... ].&nbsp;&nbsp;So
<br>my actual fromString function has more logic to handle this.<br><br>Anyway, converting an object back to a string isn't too hard; the only<br>tricky parts are including the body length in the header and computing<br>the checksum for the trailer.&nbsp;&nbsp;My code looks like this:
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;sub toString {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $this = shift;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $header = &quot;8=FIX.4.4\0019=&quot;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $body = join(&quot;\001&quot;, &quot;35=$class_2_msgType{ref $this}&quot;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map _toString($_, $this-&gt;{$_}), keys %$this) .
<br>&quot;\001&quot;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $msg = $header . length($body) . &quot;\001$body&quot;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $cksum = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cksum += ord($_) for split //, $msg;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$cksum = sprintf &quot;%03d&quot;, $cksum %256;
<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $msg . &quot;10=$cksum\001&quot;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;sub _toString {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my($key, $value) = @_;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ref $value eq 'ARRAY') {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return unless @$value;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return join &quot;\001&quot;,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;$key=&quot; . @$value,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map { my $val = $_;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my @data;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (my $i = 0; $i &lt; $#$val; $i+=2) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push @data, &quot;$tagMapping{$val-&gt;[$i]}=&quot;<br>.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$val-&gt;[$i + 1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@data;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} @$value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} elsif ($value ne '') {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &quot;$key=$value&quot;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>That's pretty much my whole FIX message base class.&nbsp;&nbsp;The constructor
<br>allows objects to be constructed from a string or from tag mnemonic =&gt;<br>value pairs.<br><br>I don't know if this helps you, but at least you see how simple it is to<br>handle parsing and generation of FIX messages.
<br><br>Benjamin Holzman<br></blockquote></div><br>