Login Page - Create Account

Support Board


Date/Time: Sat, 04 May 2024 16:14:55 +0000



Post From: [DTC] Subscribing to market data correctly

[2019-03-19 16:20:20]
User406106 - Posts: 6
I managed to solve the issue. I think, it is worth to share the solution and the lessons learned.

The hint was actually in the relay-setup steps you sent:

> Send a LOGON_REQUEST message with the LOGON_REQUEST::Integer_1 field set to 2.

The issue is again that the specification is incorrect. According to the documentation (Authentication and Connection Monitoring Messages: LOGON_REQUEST [s_LogonRequest structure] Client >> Server) the LOGON_REQUEST is an optional field

And here is the handling of unset fields with binary serialization: DTC Messages and Procedures: Indication of Unset Message Fields

This section tells how a binary serializer should treat unset fields:

> In the case of an integer, this will be INT_MAX.

But if I set this value to 0 (or I don't treat it as optional), then I can connect in non-relay mode.

________________________________________

> The documentation is 100% correct.

And sorry but I have to mention this is not correct at all. Or at least I can point out some room for improvement. Just some examples I found so far:
• SymbolID in almost every MARKET_DATA* message is still described as [unsigned int16] types in the documentation. Actually they are int32 or uint32 almost everywhere.
• I found several messages, which contain additional fields compared to the documentation. I could peek them from the C++ headers, though.
• It would be really helpful if the documentation contained the data size of the enum fields. The C++ headers may help though.
• What I really miss is an accurate binary structure layout of the fields. I struggled a lot of time with implementing a correct binary serializer even with the help of the C++ headers. It seems that the binary encoding actually reflects the in-memory layout of a specific C++ compiler, an architecture-dependent field layout, which may cause "gaps" between the fields.

The following example helps to highlight the issue (note the AlignmentFields among the actual fields):


// This is how I describe MarketDepthUpdateLevelCompact message.
// Please note the gaps I applied to reproduce the in-memory representation of the C++ version.
// These information cannot be retrieved from the documentation

private static readonly DtcField[] fields =
{
new PrimitiveField<uint>(nameof(SymbolID)),
new PrimitiveField<AtBidOrAsk>(nameof(Side)), // 2 bytes enum
new AlignmentField(2), // 2 bytes gap!
new DecimalField<float>(nameof(Price)),
new DecimalField<float>(nameof(Quantity)),
new PrimitiveField<MarketDepthUpdateType>(nameof(UpdateType)), // 1 byte enum
new AlignmentField(3), // 3 bytes gap (or MarketDepthUpdateType is int32 enum but C++ headers indicate as byte enum)
new DateTimeField(nameof(DateTime), DtcDateTime.DateTimeWithMilliseconds, true), // 8 byte double
new PrimitiveField<uint?>(nameof(NumOrders)),
};

As you can see I use a general metadata array for the fields so I do not need to reimplement the messages for supporting a new serializer as it was done in the C++ version. But this is quite a non-trivial task with these materials. Anyway, thank you for the link, it helped much highlighting the issue in my case after all.
Date Time Of Last Edit: 2019-03-19 16:23:42