To disable field encoding and enable transfer decoding in FAST

66 views
Skip to first unread message

Chetan Singh Bisht

unread,
May 18, 2017, 6:05:48 AM5/18/17
to objectcomputing_financial
I am currently working in a project where the requirement is as follows:

All messages sent by the server are transfer encoded in terms of the FAST protocol. While
all application messages sent by the server (e.g. Market Data Incremental Refresh, Security
Definition, etc.) are field encoded, the administrative messages it sends (e.g. Logon,
Heartbeat, etc.) are not. All messages (i.e. both administrative and application) initiated by
the client should be transfer encoded but not field encoded.

Can someone please help in how to achieve the above requirement?

Dale Wilson

unread,
May 18, 2017, 5:30:39 PM5/18/17
to quickfa...@googlegroups.com
I'm not quite sure what that requirement means.   

FAST is an encoding/decoding technique for messages.   Messages are encoded/decoded  by encoding the fields that make up the message.  I'm not sure how you can encode a message without encoding the fields that make up the message.

Can you clarify the requirement?

Dale

--
You received this message because you are subscribed to the Google Groups "objectcomputing_financial" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quickfast_users+unsubscribe@googlegroups.com.
To post to this group, send email to quickfast_users@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/quickfast_users/28ff69d9-267b-401d-920c-883effe3a934%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors.

Chetan Singh Bisht

unread,
May 19, 2017, 2:27:40 AM5/19/17
to objectcomputing_financial
Thanks Dale, for the reply.
You are absolutely correct Dale , I got confused with the requirement.

Actually the thing is the other party(customer) wants us to put operators in  the template xml like copy,tail etc, which I was not aware about.
Now currently I am working on copy operator. What I understand from all the document and other material available on net is that Quickfast maintains a dictionary which is used by multiples entries  within a UDP message to check the previous value.

eg:  Lets say in the below given template we can have multiple MDEntries depending upon NoMDEntries tag value. Lets say we have 2 as the value .
What I did was ,  I put the value of MDEntryType (with copy oprerator ) as 1 (some random value)  in the first entry, but for the second entry I did not put any value.
After I decode the message the value of MDEntryType should be 1 for both the entries. 

Is my understanding correct ?

<template dictionary="1" id="1" name="MDIncRefreshSample_1">
    <string id="35" name="MessageType">
        <constant value="X"></constant>
    </string>     <string id="49" name="SenderCompID">
        <constant value="Client"></constant>
    </string>     <string id="56" name="TargetCompID">
        <constant value="Server"></constant>
    </string>     <uint32 id="34" name="MsgSeqNum"></uint32>
    <uint64 id="52" name="SendingTime"></uint64>
    <sequence name="MDEntries">
        <length id="268" name="NoMDEntries"></length>
        <uint32 id="279" name="MDUpdateAction">
            <copy value="1"></copy>
        </uint32>
        <string id="269" name="MDEntryType">
            <copy value="0"></copy>
        </string>
        <uint32 id="278" name="MDEntryID"></uint32>
        <uint32 id="48" name="SecurityID">
            <delta></delta>
        </uint32>
        <decimal id="270" name="MDEntryPx">
            <exponent>
                <default value="-2"></default>
            </exponent>
            <mantissa>
                <delta></delta>
            </mantissa>
        </decimal>
        <int32 id="271" name="MDEntrySize">
            <delta></delta>
        </int32>
        <string id="37" name="OrderID"></string>
        <uint32 id="273" name="MDEntryTime">
            <copy></copy>
        </uint32>
    </sequence>
</template>


Now when I try to implement the above in my code, I am not able to copy the value in the second entry.
Here is the snippet of the code I used (help  taken from testRoundTrip.cpp)



Template Created :


  <templates> 
 <template dictionary="InstrumentReferenceData" name="InstrumentReferenceData" id="3">  
  <typeRef name="instrumentreferencedata"/>  
  <uInt32 name="timestamp" id="52"> <delta/>    </uInt32>  
  <uInt32 name="srcId" id="50">      <copy/>    </uInt32>   
 <uInt32 name="seqNum" id="34">      <increment value="1"/>    </uInt32> 
   <uInt32 name="isix" id="48">      <delta/>    </uInt32>  
  <string name="isin" id="455">      <delta/>    </string> 
   <string name="exchId" id="207">      <copy/>    </string>  
  <string name="instGrp" id="1151">      <copy/>    </string>
    <string name="instTypCod" id="461">      <copy/>    </string>    
<string name="currCode" id="15">      <copy/>    </string>    
<decimal name="ticSiz" id="969">      <delta/>    </decimal>   
 <uInt32 name="setId" id="TBD">      <copy/>    </uInt32>  
  <sequence name="MDFeedTypes">    
  <length name="noOfStreams" id="1141"/>     
 <string name="streamType" id="1022">      <copy dictionary="template" />      </string>   
   <string name="streamService">      <copy/>      </string>    
  <string name="inetAddr">        <delta/>      </string>   
   <uInt32 name="port" id="TBD">        <delta/>      </uInt32>    
  <uInt32 name="mktDepth" id="264" presence="optional"/>      
<uInt32 name="mdBookType" id="1021" presence="optional"/>   
 </sequence>
  </template>
</templates>


Message creation plus encoding and decoding:  (I have poulated the value in streamtype field only once)

 Messages::MessagePtr msg(new Messages::Message(templateRegistry->maxFieldCount()));
  msg->addField(identity_timestamp, Messages::FieldUInt32::create(1));

  msg->addField(identity_srcId, Messages::FieldUInt32::create(2));

  msg->addField(identity_seqNum, Messages::FieldUInt32::create(3));

  msg->addField(identity_isix, Messages::FieldUInt32::create(4));

  msg->addField(identity_isin, Messages::FieldAscii::create("isin"));

  msg->addField(identity_exchId, Messages::FieldAscii::create("exchId"));

  msg->addField(identity_instGrp, Messages::FieldAscii::create("instGrp"));

  msg->addField(identity_instTypCod, Messages::FieldAscii::create("instTypCod"));

  msg->addField(identity_currCode, Messages::FieldAscii::create("currCode"));

  msg->addField(identity_ticSiz, Messages::FieldDecimal::create(Decimal(123, -1)));

  msg->addField(identity_setId, Messages::FieldUInt32::create(5));

  lengthIdentity.setId("1141");
  Messages::SequencePtr sequence_MDFeedTypes(new Messages::Sequence(lengthIdentity, 2));
  Messages::FieldSetPtr entry(new Messages::FieldSet(6)); // todo Hardcoded 6?

  entry->addField(identity_streamType, Messages::FieldAscii::create("streamType"));    // Populated the value 1st time

  entry->addField(identity_streamService, Messages::FieldAscii::create("streamService"));

  entry->addField(identity_inetAddr, Messages::FieldAscii::create("inetAddr.com"));

  entry->addField(identity_port, Messages::FieldUInt32::create(2222));

  entry->addField(identity_mktDepth, Messages::FieldUInt32::create(10));



  sequence_MDFeedTypes->addEntry(Messages::FieldSetCPtr(entry));

  entry.reset(new Messages::FieldSet(6));

  entry->addField(identity_streamType, Messages::FieldAscii::create(""));     // Did not Populate the value 2nd time

  entry->addField(identity_streamService, Messages::FieldAscii::create(""));

  entry->addField(identity_inetAddr, Messages::FieldAscii::create("inetAddr.org"));

  entry->addField(identity_port, Messages::FieldUInt32::create(2224));

  entry->addField(identity_mdBookType, Messages::FieldUInt32::create(3));



  sequence_MDFeedTypes->addEntry(Messages::FieldSetCPtr(entry));

  msg->addField(identity_MDFeedTypes, Messages::FieldSequence::create(sequence_MDFeedTypes));

  Codecs::Encoder encoder(templateRegistry);
  Codecs::DataDestination destination;
  template_id_t templId = 3; // from the XML above
  encoder.encodeMessage(destination, templId, *msg);
  std::string fastString;
  destination.toString(fastString);
  std::cout<<"fastString is "<<fastString<<std::endl;

  destination.clear();

  Codecs::Decoder decoder(templateRegistry);
  Codecs::DataSourceString source(fastString);
  Codecs::SingleMessageConsumer consumer;
  Codecs::GenericMessageBuilder builder(consumer);
  decoder.decodeMessage(source, builder);

  Messages::Message & msgOut(consumer.message());

        Messages::MessageFormatter formatter(std::cout);
        formatter.formatMessage(msgOut);                                   // I have made some printing changes to print the ouptut per tag 

  validateMessage1(msgOut);


  encoder.reset();
  encoder.encodeMessage(destination, templId, msgOut);
  std::string reencoded;
  destination.toString(reencoded);

  destination.clear();



I am able to encode and successfully decode the message, but the value is not getting copied in the second entry (streamType tag).
Here is my decoded ouput:


1st entry:
 streamType[1022]=streamType                  
streamService[]=streamService
inetAddr[]=inetAddr.com
port[TBD]=


2nd entry:
streamType[1022]=                     //value not copied
 streamService[]=
inetAddr[]=inetAddr.org
port[TBD]=


Could you please let us know, if we are making a mistake somewhere. I am very new to this :)



I have following queries too :

1/ Do we need to explicitly need to enable/disable dictionary in quickfast ? (In FIX we could do that with flag, DataDictionary = Y/N). 
Also  in the template created above , I found this line:

 <string name="streamType" id="1022">      <copy dictionary="template" />      </string>   

Is it neccesary to give dictionary name while using operators and how are they related?


2/ Do we also need to explicitly mention that PMAP bits are required?

Codecs::PresenceMap pmap(1);     // I came across this function, so I got this doubt whether  we need to explicitly mention about pmap.









On Friday, 19 May 2017 03:00:39 UTC+5:30, Dale Wilson wrote:
I'm not quite sure what that requirement means.   

FAST is an encoding/decoding technique for messages.   Messages are encoded/decoded  by encoding the fields that make up the message.  I'm not sure how you can encode a message without encoding the fields that make up the message.

Can you clarify the requirement?

Dale
On Thu, May 18, 2017 at 5:05 AM, Chetan Singh Bisht <chetan...@gmail.com> wrote:
I am currently working in a project where the requirement is as follows:

All messages sent by the server are transfer encoded in terms of the FAST protocol. While
all application messages sent by the server (e.g. Market Data Incremental Refresh, Security
Definition, etc.) are field encoded, the administrative messages it sends (e.g. Logon,
Heartbeat, etc.) are not. All messages (i.e. both administrative and application) initiated by
the client should be transfer encoded but not field encoded.

Can someone please help in how to achieve the above requirement?

--
You received this message because you are subscribed to the Google Groups "objectcomputing_financial" group.
To unsubscribe from this group and stop receiving emails from it, send an email to quickfast_use...@googlegroups.com.
To post to this group, send email to quickfa...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages