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
|