- MQL5 87.9%
- Python 12.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| Files | ||
| Python | ||
| Article-24231-ONNX-Models-Part-1-Protobuf-Parser.mqproj | ||
| OMV Model.mqh | ||
| OMV Protobuf.mqh | ||
| ONNX Model Viewer Part 1.mq5 | ||
| README.md | ||
Article-24231-ONNX-Models-Part-1-Protobuf-Parser
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.