Loading…

Protobuf Wire Format Codec

A lot of modern trading infrastructure speaks Protocol Buffers, and neither MQL4 nor MQL5 has a path to a generated protobuf client - no DLL is allowed in a CodeBase submission, and there is no MQL .proto compiler on either platform. This header speaks the wire format directly: a protobuf message is nothing more than a flat sequence of (field number, wire type, payload) tuples, and that sequence can be built and read by hand once the two encodings that carry it - varints and length-delimited fields - are implemented correctly. Like the MessagePack codec elsewhere in this catalogue, this is a streaming writer and reader, not a schema-reflecting generic message class. The caller writes and reads fields in the order their own .proto schema defines, which is exactly what generated protobuf code does internally anyway - the generated getters and setters are a friendly face on the same tag-then-payload sequence this header exposes directly. The detail that separates a working implementation from a broken one is sint32/sint64. A plain varint stores a negative number as its raw two's complement bit pattern, which is all 1s in the high bits and therefore encodes as the LONGEST possible varint - ten bytes for a value as ordinary as -1. Zigzag encoding fixes this by mapping signed values to unsigned ones so small magnitudes in either direction produce small varints: 0, -1, 1, -2, 2 becomes 0, 1, 2, 3, 4. This header exposes plain varints (WriteVarint, matching int32/int64/uint32/uint64/bool/enum) and the zigzag pair (WriteSignedVarint, matching sint32/sint64) as separate functions, because using the wrong one against a real .proto schema does not raise an error - it silently produces a value that decodes to something else entirely on the other end. SkipField() advances past a field of unknown meaning using only its wire type, letting a reader tolerate a message that grew a field the reader was never told about - the exact forward-compatibility guarantee protobuf is designed around, and the reason unknown fields must never fail a decode. Notes and limitations - float (32-bit) is not implemented - only double (fixed64). A .proto field declared "float" needs its 4-byte payload read with WriteFixed32/ ReadFixed32 and the bit pattern interpreted separately if it must be matched exactly. - Wire types 3 and 4 (start_group/end_group) are the deprecated protobuf groups feature. SkipField() returns false on them rather than guessing - no current .proto schema should be emitting them. - Repeated fields are not a distinct concept here, matching how the wire format actually represents them: a repeated scalar or message field is simply the same field number written more than once, which the demo's ReadTag() loop already handles without any special casing. - Packed repeated fields (a single length-delimited blob holding many varints back to back) are not unpacked automatically - read the field as ReadBytes() and loop ReadRawVarint-style parsing over the payload yourself if a schema uses packed encoding. - ReadVarint() widens every value to a 64-bit signed long. A genuinely unsigned uint64 above LONG_MAX will read back negative on both platforms - neither MQL4 nor MQL5 has an unsigned 64-bit type to hold it correctly.

Script · MT5 · v1.0 · Free

About Protobuf Wire Format Codec

Protobuf Wire Format Codec is a script for MetaTrader 5. MQL source code included.

Files in the download: ProtobufWireCodec.mq5.mqh, ProtobufWireCodec.txt, ProtobufWireCodecDemo.ex5, ProtobufWireCodecDemo.mq5.

How to install

  1. Download the ZIP from your PolyMaria library and unzip it.
  2. In MetaTrader 5 open File → Open Data Folder, then go to MQL5 → Scripts.
  3. Copy the .mq5 file(s) there. Put any .mqh files in MQL5 → Include.
  4. Open the .mq5 file in MetaEditor and press Compile (F7) if MetaTrader does not show it.
  5. Drag the script onto a chart to run it once.

Download the PDF guide

Tags: MT5 Script · MQL5 Source Code

MQL4 & MQL5 scripts · PolyMaria