Source code for the MQL5 article *Working with ONNX Models in MQL5 (Part 1): Decoding the Model File with a Protobuf Parser*.
https://www.mql5.com/en/articles/24231
## What it does
An ONNX file is a Protocol Buffers message. MetaTrader can run such a model through `OnnxCreate`, but it will not tell you what is inside one — the operators, the tensor shapes, or the weight ranges.
This project reads the bytes directly. It implements the protobuf wire format in pure MQL5, walks the ONNX message hierarchy on top of it, and prints the model structure to the Experts log. No DLLs, no external libraries, no runtime call.
## Files
ONNX Model Viewer Part 1.mq5 Expert Advisor, reports the model
OMV Protobuf.mqh CPbReader, protobuf wire format
OMV Model.mqh COmvModel, ONNX message layer
Files/model.onnx Pre-built test model
Python/make_model.py Script that generates it
The two headers use quoted relative includes and must stay next to the `.mq5`.
## How it works
`CPbReader` is a byte cursor that knows nothing about ONNX. It decodes varints, splits tags into field number and wire type, reads length-prefixed strings and nested blocks, and reinterprets raw bits as `float` and `double` through unions. It carries a failure flag rather than throwing, so a malformed length stops the parse cleanly.
`COmvModel` sits on top and knows the ONNX field numbers. `Load` walks the graph and fills three structures — `OmvNode` for layers, `OmvTensor` for weights, `OmvPort` for exposed inputs and outputs. Both tensor storage paths are handled: typed `float_data` fields and packed `raw_data` blocks. Min, max and mean are computed during the parse. Capacity is capped by the `OMV_MAX_*` constants — 512 nodes, 512 tensors, 8 ports per side, 8 dimensions — and anything larger is truncated rather than rejected.
The EA itself is thin. `OnInit` loads the model and prints the header fields, the ports, the layers, and optionally every weight tensor. There is no `OnTick`.
## Setup
Copy `model.onnx` into `MQL5\Files\ONNX Model Viewer Part 1\`. MQL5 can only read from the `Files` sandbox, so it will not be found anywhere else. Compile, attach to any chart, and check the Experts tab. Symbol and timeframe do not matter.
To regenerate the model instead: `pip install onnx numpy`, then run `make_model.py`. It writes to the correct folder itself.
## The test model
A small network built to exercise the parser rather than to trade: 16 inputs, two branches of 8 with ReLU, concatenated, through a merged layer of 10, to 3 outputs. The branching gives the parser a graph that is not a straight line.
`Wa` is written through `float_data` while the rest use `raw_data`, so both paths are covered. `scale` is stored as `double` so the parser meets a second element type. Opset 13, IR version 8, a custom domain and three metadata pairs are set so the header fields are populated. Fixed seed, so the weights are reproducible.