Contents

  1. Audience
  2. Scope
  3. Introduction
  4. Applications Considered
    1. Vulnerable Applications
      1. OMM Applications Using UPA or RFA Version 7.x and Earlier Releases
        1. RFA Java 7.x and Earlier Releases
        2. RFA C++ 7.x and Earlier Releases
        3. UPA Java 7.x and Earlier Releases.
        4. UPA C 7.x and Earlier Releases.
      2. 32-bit RFA OMM Applications.
    2. Applications using a Non-OMM API.
      1. Applications Using RFA MarketData Interfaces.
      2. Applications Using Legacy TREP APIs.
  5. Solutions
    1. Upgrade API
    2. Exception Handling
    3. Pre-Decoding Check
    4. Post-Decoding Check
  6. Custom Dictionary.
  7. Using The High Precision Time Values.
  8. Glossary
  9. References

Audience

Developers responsible for maintenance of application code where it makes use of RFA or UPA and will be potentially exposed to the new high precision time fields.

Scope

This article provides a synopsis for the coding aspects of high precision time fields. Including; what applications are vulnerable when confronted with the high precision time fields, what to expect when this occurs and what you can do to ensure an application continues to operate correctly.

The factors informing the decision to add high precision time fields into applications or avoid them altogether is outside the scope of this article.

For further information see MiFID II - Extending the precision of timestamps supported on Elektron Real Time.

Introduction.

Following on from the Webinar session Introduction to MiFID II for Developers I wanted to add some detail on the coding aspects of handling (or avoiding) the high precision time, not covered in the Webinar and include some information based on questions arising after the event.

For clarity, in the code extracts that follow, logging is used to illustrate the occurance and handling of the error or exception but in a production configuration this should be avoided when a time field raises the expected error or exception because the frequency with which this occurs will have an adverse effect on update processing performance.

Applications Considered.

We will look at the following application types, if any action is required, where applicable what error is produced, with a brief description so that you can recognise when it has occurred in your application and what solutions are available;

 Vulnerable Applications

Applications at risk of failures when high precision time values are present in the data.

TESTING NOTE: Failure will only occur when the microsecond or nanosecond components of the time value are populated, it is therefore essential that this is the case for any valid testing scenario in order to avoid the risk of a false positive test result.. e.g. Log the data being consumed by the application under test using a seperate application such as rmdstestclient that is capable of decoding high precision time values and check for the presence of micro-second or nano-second time values in the data during the testing period.

 OMM Applications Using UPA or RFA Version 7.x and Earlier Releases

Existing OMM Applications using a version of RFA or UPA earlier than version 8.x will experience an error if it encounters a high precision time value during the decoding process. Applications that only use specific fields and do not attempt to decode any of the new high precision time fields (currently field names suffixed "_NS" by convention) will not encounter an error but in some cases applications which match this profile extract the value before determining if it is a required field and trigger an error as a result, therefore such applications must be thoroughly tested against data containing high precision time values.

 RFA Java 7.x and Earlier Releases

When a Time field is encountered with either the microsecond or nanosecond components of the time value populated the API will raise an exception : com.reuters.rfa.omm.OMMException. with a message similar to this:

Exception in thread "main" com.reuters.rfa.omm.OMMException: Invalid size 8 for Time

The size reported is the encoded length determined by the presence of microsecond and nanosecond components.

Triggered in method:

com.reuters.rfa.omm.OMMData com.reuters.rfa.omm.OMMFieldEntry.getData(short type)

 

e.g.

// OMMData data 
// OMMFieldEntry fe 
// com.reuters.rfa.dictionary.FidDef fiddef 
data = fe.getData(fiddef.getOMMType());
Solutions Available.

For applications using RFA Java 7.x and Earlier Releases, the solutions available are as follows:

  1. Consider upgrading to one of the compatible API releases listed below.
  2. Implement Pre-Decoding Checks.
  3. Implement Exception Handling.

Upgrading the API and Pre-decoding check for high precision time values are mutually exclusive. Implementing Exception Handling is compatible and recommended for both Pre-Decoding checks and upgrading the API.

 RFA C++ 7.x and Earlier Releases

When a Time field is encountered with either the microsecond or nanosecond components of the time value populated the API will raise an exception : InvalidUsageException with a message:

"Data decoding failed in DataBuffer::getTime(); Reason: RSSL_RET_INCOMPLETE_DATA".

Triggered in method:

const rfa::data::Time& rfa::data::DataBuffer::getTime () const;

 

But any method that implcitly requires access to the field data can raise this same exception and message, e.g.

bool rfa::data::DataBuffer::isBlank() const;

 

Solutions Available.

The solutions available for applications using RFA C++ 7.x and Earlier Releases are:

  1. Consider upgrading to one of the compatible API releases listed below.
  2. Implement Pre-Decoding Checks.
  3. Implement Exception Handling.

Upgrading the API and Pre-decoding check for high precision time values are mutually exclusive. Implementing Exception Handling is compatible and recommended for both Pre-Decoding checks and upgrading the API.

 UPA Java 7.x and Earlier Releases

When a Time field is encountered with either the microsecond or nanosecond components of the time value populated the API will return an error: RSSL_RET_INCOMPLETE_DATA. Triggered in method:

 int com.thomsonreuters.upa.codec.Time.decode(DecodeIterator iter)
Solutions Available.

For applications using UPA Java 7.x and Earlier Releases the solutions available are as follows:

  1. Consider upgrading to one of the compatible API releases listed below.
  2. Implement Pre-Decoding Checks.
  3. Implement Post-Decode Error Handling.

For defensive coding against high precision time values you should consider the above options as mutually exclusive, i.e. either do (1), (2) or (3).

 UPA C 7.x and Earlier Releases

When a Time field is encountered with either the microsecond or nanosecond components of the time value populated the API will return an error value defined in enum RsslReturnCodes : RSSL_RET_INCOMPLETE_DATA (-26). Triggered in method:

 RSSL_API RsslRet rsslDecodeTime( RsslDecodeIterator *pIter, RsslTime *value );
Solutions Available.

For applications using UPA C 7.x and Earlier Releases the solutions available are as follows:

  1. Consider upgrading to one of the compatible API releases listed below.
  2. Implement Pre-Decoding Checks.
  3. Implement Post-Decode Error Handling.

For defensive coding against high precision time values you should consider the above options as mutually exclusive, i.e. either do (1), (2) or (3).

 32-bit RFA OMM Applications

Any existing 32-bit RFA OMM applications will be using a release earlier than version 8.x and will fail if it attempts to decode a high precision time value as described for RFA C++ 7.x and Earlier Releases.

Solutions Available.

Solutions available for 32-bit RFA OMM Applications are:

  1. Consider upgrading to one of the compatible API releases listed below: For those 32-bit RFA OMM applications that cannot be migrated to 64 bit at this time, the RFA 8.1.0.L1 release is supplied with 32-bit libraries, upgrading to this release will allow your application to operate when high precision time values are present in the data - but make sure your target OS and compiler are supported. If the application cannot be upgraded then the solutions available are the same as those given for 64-bit applications, i.e.
  2. Implement Exception Handling.
  3. Implement Pre-Decoding Checks.

Upgrading the API and Pre-decoding checks for high precision time values are mutually exclusive. Implementing Exception Handling is compatible and recommended for both Pre-Decoding checks and upgrading the API.

Applications Using Non-OMM APIs

An Application using a Non-OMM API will not be able to access the high precision time values; These new Time fields will yield a blank or be truncated to seconds, depending on the infrastructure version in use. Any such application should be subject to a requirements review to ensure that the regulatory changes do not neccesitate access to the high precision time values.  

 Applications Using RFA MarketData Interfaces

Because existing RFA MarketData applications will not have access to the high precision time values it will therefore not encounter an error when these are introduced into the instruments.

Applications using the RFA Market Data interface cannot be upgraded to version 8 because this interface has been removed from the release since version 8. If access to the high precision time fields is required it must be migrated to use the OMM interfaces using one of the compatible API releases.

Identifying the use of Legacy RFA MarketData Interfaces

Applications using legacy RFA Market Data interfaces can be identified by the use of any interface or class name starting 'MarketData' such as MarketDataSubscriber, but also the use of any interfaces with a name starting 'Tib' such as TibMsg or TibField. These applications can also be identified by their API configuration settings; The 'connectionType' parameter will be using a setting of "SASS3", "SSL" or ""SSLED" depending on the legacy protocol and RFA edition employed.

 Applications Using Legacy TREP APIs

A legacy TREP API includes SFC (Java, C++ or COM) or SSL (C), for more information see "Thomson Reuters Enterprise Platform - Legacy APIs".  No error will be encountered when the high precision time values are introduced to the instruments but if such an application requires access to them it must be migrated to one of the compatible API releases. Given that the RFA is now feature complete (i.e. no further development), it is recommeded that a strategic API is used e.g. Elektron Messaging API (EMA). More information is available on the Developer Portal about our strategic Elektron APIs.

Solutions.

A Summary of the following potential solutions with example code extracts where applicable;

  1. Upgrade API.
  2. Implement Exception Handling.
  3. Implement Pre-Decoding Check.
  4. Post-Decode Check.

 Solution: Upgrade API

Supported Operating Systems and Compilers

When considering an upgrade to any of the APIs listed below please ensure your target Operating System and compiler versions are supported, the latest information is listed in the API Compatibility Matrix, this is updated as and when support is added or removed. The release note also contains this information at the time of the release.

There are links to the Developer Web Portal in the tables below, where the example versions are given, each has a link to the appropriate release note, there is also a link to the API Compatibility Matrix associated with the API name.

 APIs Compatible With High Precision Time Fields

The APIs that can already decode the new high precision time fields are;

  1. All APIs bundled with the Elektron SDK i.e.
API Language Version
Elektron Messaging API (EMA) C++ Any, e.g. ema3.1.1.L1.win, see download page
Elektron Transport API (ETA) C Any, e.g. eta3.1.1.L1.win
Elektron Messaging API (EMA) Java Any, e.g. emaj3.1.1.L1.all, see dowload page
Elektron Transport API (ETA) Java Any, e.g. etaj3.1.1.L1.all
  1. All UPA 8.x releases
API Language Version
UPA C 8.x e.g. upa8.0.0.L1.winupa8.0.0.L1.linuxupa8.0.0.L1.solaris, see download page
UPA Java 8.x e.g. upaj8.0.0.L1.all.rrg, see download page
  1. All RFA 8.x releases Please Note that the RFA is now feature complete (i.e. no further development), it is recommeded that a strategic API is used e.g. Elektron Messaging API (EMA) unless the application is already implemented with an existing version of RFA OMM Interface.
API Language Version
RFA C++ 8.x e.g. rfa8.1.0.L1.win-shared, rfa8.1.0.L1.win-static,rfa8.1.0.L1.linux. see download page
RFA Java 8.x e.g. rfaj8.1.0.L1.all.rrg, see download page

The Technical Bulletin IMPACT OF WIRE FORMAT CHANGES ON THE APIS provides some background on versions supporting the introduction of high precision time.

 Solution: Exception Handling

Applicable to RFA.

Although we are looking at Exception Handling specifically for defensive coding in the presence of high-precision timestamps for RFA versions earlier than 8.x, please take note of the Technical Bulletin "RFA AND EXCEPTION HANDLING" which advises its more general use.

All the exception handling examples are specifically designed to allow the application to continue processing the remaining data in the Field List after encountering a high precision time value, for performance reasons a more general exception handling policy would protect the application from complete failure but would not allow the remaining data to be processed. Such a policy would be implemented by placement of try-catch statements so that it is executed only once during the event processing method, e.g. on entry to the processEvent() method.

  NOTE: If the presence of high precision time values are not an exception within the data-set on which the application will operate follow the advice in the Technical Bulletin  "RFA AND EXCEPTION HANDLING" ,  as a more general approach to making your application more robust but to avoid frequently triggering exceptions use Pre-Decoding Checks.

Advantages.

  • A general solution that allows an application to continue operating when confronted with decoding exceptions including, but not limited to, any high precision time or date-time values.
  • When an application is upgraded to version 8.x or later, the new fields will automatically become accessible, the application exception handling code remains valid and in place without change - it is simply no longer triggered by the new time fields because the new API version can decode them.

Disadvantages

  • The expense of setting up exception handling within update handlers is less attractive for applications with high performance requirements.
  • Triggering and handling exceptions is expensive in terms of performance cost, see exception handling note above
  • When processing Time fields the application cannot determine the difference between encountering a high precision time value and a genuine Exception.

Implementation : RFA Java

To illustrate where to catch com.reuters.rfa.omm.OMMException when decoding a high precision timestamp value we will use RFA Java version rfaj7.6.1 and the example com.reuters.rfa.example.omm.cons.StarterConsumer.java from that Devkit.

File: GenericOMMParser.java

Method:

private static final void parseEntry(OMMEntry entry, PrintStream ps, int tabLevel)

Line: 663

    { // Start of method body.
    	try // try-catch to defend against decoding errors on new _NS Time fields.
        {	// Original code starting with switch statement...
            switch (entry.getType())

Line: 745

		default:
			dumpEntryHeader(entry, ps, tabLevel);
			parseData(entry.getData(), ps, tabLevel);
			break;
	   } //End of switch statement with no alterations.
	} // catch to defend against decoding errors on new _NS Time fields. 
	catch (OMMException e)
	{
		ps.println("ERROR Invalid data: " + e.getMessage());
	}

Placement of the try-catch block within the parseEntry() method allows the application to continue processing the remaining fields in the FieldList after encountering a high precision time value.

Implementation : RFA C++

To illustrate where to catch InvalidUsageException when decoding a high precision timestamp value we will use RFA C++ version rfa7.6.2.L1.win-shared.rrg and the StarterConsumer example from that Devkit.

File: ..\StarterCommon\Decoder.cpp Method:

void Decoder::decodeFieldEntry( const FieldEntry& input )

Line: 173

	if(_fd)
		fprintf(_fd, "\t");
	//Exception Handling code starts here;
	// enclose decodeData call in try block if it is a time field.
	if( _pCurrentFidDef->getOMMType() == rfa::rdm::RDMFidDef::RWF_TYPE_TIME  )
	{
		try {
		decodeData( input.getData(static_cast<UInt8>(_pCurrentFidDef->getOMMType())) );
		} // Add catch statement for the expected InvalidUsageException
		catch( InvalidUsageException& iue )
		{
			AppUtil::log(__LINE__, AppUtil::WARN, 
                         "Decoder::decodeFieldEntry() - Error decoding OMMType %d: %s\n"
				,_pCurrentFidDef->getOMMType(), iue.getStatus().getStatusText().c_str());
		} 
	}
	else //Exception Handling code ends here.
		decodeData( input.getData(static_cast<UInt8>(_pCurrentFidDef->getOMMType())) );

 Solution: Pre-Decoding Check

Applicable to: UPA and RFA versions earlier than 8.x. All editions.

Test the encoded length of the incoming time field. This will allow an application to identify if it exceeds the prescribed encoded-length limit for the API version employed and thereby avoid decoding that field. Thus the application continues to operate.

Advantages

  • More efficient than try-catch exception handling constructs.

Disadvantages

  • Requires more code effort in comparison with exception handling. All of the code points that explicitly decode the time value and those that implicitly access the time value (e.g. DataBuffer::isBlank()) must be changed.
  • In testing terms more effort is required because all the code-paths must be exercised in order to ensure that the defensive code is complete and correct.
  • This approach is designed to handle a specific problem, other issues will still throw an exception e.g. an invalid time range.
  • When the application is upgraded all the pre-decode checks must be removed before it can access the new time fields.

Implementation : RFA Java

To illustrate how to check for a high precision timestamp value before it triggers an exception we will use RFA Java version rfaj7.6.1 and the example com.reuters.rfa.example.omm.cons.StarterConsumer.java from that Devkit.

File: GenericOMMParser.java

Method:

private static final void parseEntry(OMMEntry entry, PrintStream ps, int tabLevel)

Line: 679

	if (fe.getDataType() == OMMTypes.UNKNOWN)
	{ // New code starts here
	  //Test the data-type is a TIME field and its length exceeds the maximum for this RFA version.
		if(fiddef.getOMMType()==OMMTypes.TIME && fe.getData().getEncodedLength()>5)
		{
			System.out.println("FID "+fe.getFieldId()+" Invalid size "+
					fe.getData().getEncodedLength()+" for TIME.");
			return; // Do not decode this data.
		} // else it is safe to decode as before...
		data = fe.getData(fiddef.getOMMType());
	} // New code ends here
	else
		// defined data already has type

 

Implementation: RFA C++

Using RFA C++ release rfa7.6.2.L1.win-shared.rrg and example StarterConsumer from that DevKit to illustrate checking for a high precision timestamp value before it triggers an exception. File: ..\StarterCommon\Decoder.cpp Method:

void Decoder::decodeFieldEntry( const FieldEntry& input )

Line : 173

if(_fd)
		fprintf(_fd, "\t");
	// Pre-Decode Check Starts here...
	// Get the Data from the FieldEntry
	const rfa::common::Data& data = input.getData(
                                    static_cast<UInt8>(_pCurrentFidDef->getOMMType()));
	// If the data-type is a TIME field and its length exceeds the maximum for this RFA version.
	if( _pCurrentFidDef->getOMMType() == rfa::rdm::RDMFidDef::RWF_TYPE_TIME 
		&& data.getEncodedBuffer().size() > 5 )
	{
		// then do not decode this field
		AppUtil::log(__LINE__, AppUtil::WARN, 
                     "Decoder::decodeFieldEntry() - Invalid data, OMMType %d: length %d\n"
			,_pCurrentFidDef->getOMMType(), data.getEncodedBuffer().size());
	}
	else // Pre-Decode Check Ends here...
		// it is safe to decode as before...
		decodeData( input.getData(static_cast<UInt8>(_pCurrentFidDef->getOMMType())) );

 

Implementation: UPA Java

Using UPA Java version upj7.4.0.L1.all.rrg

Using DevKit Example: com.thomsonreuters.upa.examples.consumer

File: MarketPriceHandler.java

Method:

protected int decodeFieldEntry(FieldEntry fEntry, DecodeIterator dIter, DataDictionary dictionary, StringBuilder fieldValue)

Line 710 :

case DataTypes.TIME:
	if( fEntry.encodedData().length()>5)
	{
		//Pre-decode check
		System.out.println(
		    "Pre-decode check: aborted Time.decode(); Length= "+
			fEntry.encodedData().length());
		return CodecReturnCodes.SUCCESS;
	}
    ret = fidTimeValue.decode(dIter);

 

Implementation: UPA C

Using UPA C version upa7.6.1.L1.win.rrg

Using DevKit Example: rsslConsumer

File: Examples\rsslConsumer\rsslMarketPriceHandler.c

Method:

RsslRet decodeFieldEntry(RsslFieldEntry* fEntry, RsslDecodeIterator *dIter)

Line 1318 :

case RSSL_DT_TIME:
	// Start of Pre-decoding check...
	if( fEntry->encData.length > 5 )
	{
		printf("rsslDecodeTime(); RSSL_DT_TIME encoded data length = %d\n",
			fEntry->encData.length);
		return RSSL_RET_SUCCESS;
	}
	// End of Pre-decoding check code.
	if ((ret = rsslDecodeTime(dIter, &fidDateTimeValue.time)) == RSSL_RET_SUCCESS))

 

 Solution: Post-Decode Check

Applicable to: UPA versions earlier than 8.x. All editions.

Test the return code after decoding the incoming time field for the error associated with an attempt to decode a high precision time value, allowing the application to continue.

Advantage

  • More efficient than try-catch exception handling constructs.

Disadvantages

  • When processing Time fields the application cannot determine the difference between a high precision time value and a genuine RSSL_RET_INCOMPLETE_DATA error.

Implementation: UPA C

Using UPA C version upa7.6.1.L1.win.rrg

Using DevKit Example: rsslConsumer

File: Examples\rsslConsumer\rsslMarketPriceHandler.c

Method:

RsslRet decodeFieldEntry(RsslFieldEntry* fEntry, RsslDecodeIterator *dIter)

Line 1318

case RSSL_DT_TIME:
	if ((ret = rsslDecodeTime(dIter, &fidDateTimeValue.time)) == RSSL_RET_SUCCESS)
	{
		fidDateTimeBuf.data = (char*)alloca(30);
		fidDateTimeBuf.length = 30;
		rsslDateTimeToString(&fidDateTimeBuf, RSSL_DT_TIME, &fidDateTimeValue);
		printf("%s\n", fidDateTimeBuf.data);
	}
	else if (ret != RSSL_RET_BLANK_DATA)
	{
		printf("rsslDecodeTime() failed with return code: %d\n", ret);
		// Start of Post-Decode check to defend against decoding errors 
		// on new _NS Time fields.
		if( ret == RSSL_RET_INCOMPLETE_DATA )
			return RSSL_RET_SUCCESS;
		else // End of Post-Decode check.
			return ret;
	}
	break;

 

Implementation: UPA Java

Using UPA Java version upj7.4.0.L1.all.rrg

Using DevKit Example: com.thomsonreuters.upa.examples.consumer

File: MarketPriceHandler.java

Method:

protected int decodeFieldEntry(FieldEntry fEntry, DecodeIterator dIter, DataDictionary dictionary, StringBuilder fieldValue)

Line 710 :

	case DataTypes.TIME:
		ret = fidTimeValue.decode(dIter);
		if (ret == CodecReturnCodes.SUCCESS)
		{
			fieldValue.append(fidTimeValue.toString());
		}
		else if (ret != CodecReturnCodes.BLANK_DATA)
		{
			System.out.println("DecodeTime() failed: <" +
					CodecReturnCodes.toString(ret) + ">");
			// Start of Post-Decode defensive check: 
			// To enable the application to operate correctly when encountering
			// decoding errors on new _NS Time fields.
			if( ret == CodecReturnCodes.INCOMPLETE_DATA )
			{
				return CodecReturnCodes.SUCCESS;
			}
			else	// End of Post-Decode defensive check. 
			return ret;
		}

 

 Using A Custom Dictionary

Applicable to: RFA and UPA.

There is an approach to avoid decoding high precision time fields which requires maintainance of a separate data dictionary that does not contain the new high precision time fields, particularly for applications that cannot upgrade.

It is not suggested as a solution in this article but it is given some attention here because of reported issues in the field; You may consider it because it appears to offer a solution with the possibility of no code change or upgrade required in the application, if you are considering this tactic please note the following caveats:

Caveats

  1. Some editions of RFA used exceptions when a field it attempted to decode was not present in the data dictionary. RFA C++ and Java editions will return null, in either case ensure your application manages this correctly. e,g, null pointer or unhandled exceptions.
  2. Must ensure that the performance profile of the application is not adversely affected by the additional processing introduced by handling the missing FIDs.
  3. Because of item 1. and 2. above this approach can only be used to protect the application where the presence of high precision time fields are an exceptional circumstance  and not part of the data-set on which the application is expected to operate.  
  4. Thorough testing required - there is no rollback.
  5. Short term solution. The technology allows any TIME data type to deliver high precision time, this strategy relies on adherence to the convention that Thomson Reuters will only publish high precision time values on fields suffixed '_NS'. Consequently any changes to this convention will require changes to the application and/or the dictionary.
  6. The introduction of any new '_NS' fields must be removed from updates applied to the custom dictionary.
  7. This creates potentially significant additional infrastructure setup and operational maintenance overheads to manage two distinct dictionaries including how they are delivered to the application.
  8. Other issues will still throw an exception e.g. an invalid time range.

Decoding High Precision Time Fields

The two examples below illustrate the extraction of all the components of a high precision time value, the extracts of the resulting outputs are from a payload containing the following fields.

Sample Payload
Fid Name Value
2 RDNDISPLAY 116
6 TRDPRC_1 14.57
14263 ASK_TIM_NS (blank data)
14264 BID_TIM_NS 13:02:35.997.0.0
14265 QUOTIM_NS 13:02:35.997.998.999
19 OPEN_PRC 84.94
4 RDN_EXCHID 202

 

 

 

 

 

 

 

 

 

Note:

  • The time field "ASK_TIM_NS" is encoded as blank,
  • "BID_TIM_NS" is populated up to millisecond (the microsecond and nanosecond components are blank) and
  • "QUOTIM_NS" is fully populated including microseconds and nanoseconds.

RFA Java Example

RFA Java rfaj8.0.1.L1.all.rrg

Using DevKit Example: com.thomsonreuters.upa.examples.consumer

File: GenericOMMParser.java

Method:

public static final void parseData(OMMData data, PrintStream ps, int tabLevel)

Line: 561

try { 
       // ADDED: To show access to the microsecond and nanosecond components 
       // of a high precision timestamp 
       if( data.getType() == OMMTypes.TIME ) 
       { 
         OMMDateTime dtd = (OMMDateTime)data; 
         ps.println(String.format(" TIME: %02d:%02d:%02d.%d.%d.%d ", 
                 dtd.getHour(), dtd.getMinute(), dtd.getSecond(), dtd.getMillisecond(), 
                 dtd.getMicrosecond(), dtd.getNanosecond())); 
       } 
       else ps.println(data); 
    } 
    catch (Exception e) 
    { 
       byte[] rawdata = data.getBytes(); 
       ps.println(HexDump.hexDump(rawdata));
    }

Output:

...

FIELD_ENTRY 14263/ASK_TIM_NS:

FIELD_ENTRY 14264/BID_TIM_NS: TIME: 13:02:35.997.0.0

FIELD_ENTRY 14265/QUOTIM_NS: TIME: 13:02:35.997.998.999

...

EMA C++ Example.

Using EMA C++ version ema3.1.1.L1.win ( from Elektron-SDK1.1.1.win.rrg)

Example: 120__MarketPrice__FieldListWalk

Contained in directory: <ElektronSDK>\Ema\Examples\Training\Consumer\100_Series_Examples\

File: Consumer.cpp

Line: 55

void AppClient::decode( const FieldList& fl ) 
{ 
   while (fl.forth()) 
   { 
      // Code added to show extraction of individual time components starts here 
      const thomsonreuters::ema::access::FieldEntry& fe = fl.getEntry(); 
      // Check the FieldEntry is a Time value and not blank - extracting a time value 
      // when FieldEntry::getCode() returns Data::BlankEnum is an error and will 
      // raise OmmInvalidUsageException. 
      if (fe.getCode() != Data::BlankEnum && fe.getLoadType() == DataType::TimeEnum) 
      { 
         const OmmTime& ot = fe.getTime(); 
         // Access the data as OmmTime. 
         cout << "Fid: " << fe.getFieldId() << " Name: " << fe.getName() << " OmmTime value: " 
              << (int)ot.getHour() << ":" << setfill('0') << setw(2) << (int)ot.getMinute()<< ":" 
              << setfill('0') << setw(2) << (int)ot.getSecond() << "." << (int)ot.getMillisecond() 
              << "." << (int)ot.getMicrosecond() << "." << (int)ot.getNanosecond() << endl; 
      } 
      else // Code added to show extraction of individual time components ends here 
           cout << "Fid: " << fl.getEntry().getFieldId() << " Name: " << fl.getEntry().getName() 
                << " value: " << fl.getEntry().getLoad().toString() << endl; 
   } 
}

Output:

...

Fid: 14263 Name: ASK_TIM_NS value: (blank data)

Fid: 14264 Name: BID_TIM_NS OmmTime value: 13:02:35.997.0.0

Fid: 14265 Name: QUOTIM_NS OmmTime value: 13:02:35.997.998.999

...

 Glossary

Term Description
RFA Robust (formerly 'Reuters') Foundation API. It Provides a single, low-level, thread-safe API that applications can use with Thomson Reuters’s systems to publish and consume data. This API is now feature-complete in terms of its development lifecycle. It consisted of an OMM interface and a legacy MarketData interface.
UPA Ultra Performance API. This is a transport layer API which has now been incorporated into the strategic Elektron SDK as the Elektron Transport API (ETA).
OMM Open Message Model
TREP Thomson Reuters Enterprise Platform for Real-Time
EMA Elektron Messaging API. A strategic API available in C++ and Java which is part of the API suite provided with the Elektron SDK.
ETA Elektron Transport API. A strategic API available in C and Java which is part of the API suite provided with the Elektron SDK.
SSL Sink Source Library. A legacy 'C' language Marketfeed API.
SFC System (formerly SSL) Foundation Classes. A legacy API release for C++, Java and COM.

 References

MiFID II - Extending the precision of timestamps supported on Elektron Real Time

Webinar Recording: Introduction to MiFID II for Developers on YouTube

Technical Bulletin: IMPACT OF WIRE FORMAT CHANGES ON THE APIS UPA CUPA JavaRFA C++RFA Java

Technical Bulletin: RFA AND EXCEPTION HANDLING

The TREP API Family Compatibility Matrix for RFA Java RFA C++RFA .NET, UPA Java and UPA C

Thomson Reuters Enterprise Platform - Legacy APIs