2026-09-03 22:12:24 +03:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| ONNX Model Viewer Part 1.mq5 |
|
|
|
|
|
//| Copyright 2026, Allan Munene Mutiiria. |
|
|
|
|
|
//| https://t.me/Forex_Algo_Trader |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, Allan Munene Mutiiria."
|
|
|
|
|
#property link "https://t.me/Forex_Algo_Trader"
|
|
|
|
|
#property version "1.00"
|
|
|
|
|
#property strict
|
|
|
|
|
#property description "Read an ONNX model file and report its structure"
|
|
|
|
|
|
|
|
|
|
#include "OMV Model.mqh"
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Inputs |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
input group "Model"
|
|
|
|
|
input string ModelFile = "ONNX Model Viewer Part 1\\model.onnx"; // Model File Path Inside MQL5 Files
|
|
|
|
|
input bool ShowWeights = true; // List Every Weight Tensor
|
|
|
|
|
|
2026-09-03 22:23:47 +03:00
|
|
|
|
2026-09-03 22:12:24 +03:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Global Variables |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
COmvModel model; // Parsed model held for the life of the chart
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Report one exposed port |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void ReportPort(const OmvPort &port, const string role)
|
|
|
|
|
{
|
|
|
|
|
//--- Print the role, name, element type and shape on one line
|
|
|
|
|
PrintFormat(" %-6s %-10s %-7s %s", role, port.name,
|
|
|
|
|
model.TypeName(port.elemType),
|
|
|
|
|
model.DimsText(port.dim, port.dims));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Report every exposed port |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void ReportPorts(void)
|
|
|
|
|
{
|
|
|
|
|
//--- Print how many ports sit on each side
|
|
|
|
|
PrintFormat(" ports: %d in, %d out", model.Inputs(), model.Outputs());
|
|
|
|
|
//--- Print every graph input
|
|
|
|
|
for(int i = 0; i < model.Inputs(); i++)
|
|
|
|
|
{
|
|
|
|
|
//--- Fetch this input
|
|
|
|
|
OmvPort port;
|
|
|
|
|
model.InputAt(i, port);
|
|
|
|
|
//--- Print it
|
|
|
|
|
ReportPort(port, "in");
|
|
|
|
|
}
|
|
|
|
|
//--- Print every graph output
|
|
|
|
|
for(int i = 0; i < model.Outputs(); i++)
|
|
|
|
|
{
|
|
|
|
|
//--- Fetch this output
|
|
|
|
|
OmvPort port;
|
|
|
|
|
model.OutputAt(i, port);
|
|
|
|
|
//--- Print it
|
|
|
|
|
ReportPort(port, "out");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Report every layer |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void ReportNodes(void)
|
|
|
|
|
{
|
|
|
|
|
//--- Print how many layers the graph holds
|
|
|
|
|
PrintFormat(" nodes: %d", model.Nodes());
|
|
|
|
|
//--- Print every layer in file order
|
|
|
|
|
for(int i = 0; i < model.Nodes(); i++)
|
|
|
|
|
{
|
|
|
|
|
//--- Fetch this layer
|
|
|
|
|
OmvNode node;
|
|
|
|
|
model.NodeAt(i, node);
|
|
|
|
|
//--- Join the names feeding it
|
|
|
|
|
string feeds = "";
|
|
|
|
|
for(int j = 0; j < node.feedCount; j++)
|
|
|
|
|
feeds += (j > 0 ? ", " : "") + node.feeds[j];
|
|
|
|
|
//--- Join the names it produces
|
|
|
|
|
string emits = "";
|
|
|
|
|
for(int j = 0; j < node.emitCount; j++)
|
|
|
|
|
emits += (j > 0 ? ", " : "") + node.emits[j];
|
|
|
|
|
//--- Print the layer with both name lists
|
|
|
|
|
PrintFormat(" %2d %-10s %-14s in(%s) out(%s)", i, node.op, node.name, feeds, emits);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Report every weight tensor |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void ReportTensors(void)
|
|
|
|
|
{
|
|
|
|
|
//--- Print how many tensors and weights the file carries
|
|
|
|
|
PrintFormat(" tensors: %d holding %d parameters", model.Tensors(), model.Parameters());
|
|
|
|
|
//--- Stop when the user asked for the summary only
|
|
|
|
|
if(!ShowWeights)
|
|
|
|
|
return;
|
|
|
|
|
//--- Print every tensor with its shape and range
|
|
|
|
|
for(int i = 0; i < model.Tensors(); i++)
|
|
|
|
|
{
|
|
|
|
|
//--- Fetch this tensor
|
|
|
|
|
OmvTensor tensor;
|
|
|
|
|
model.TensorAt(i, tensor);
|
|
|
|
|
//--- Print the name, shape and size every tensor has
|
|
|
|
|
PrintFormat(" %-6s %-10s %-8s %-7s %6d values%s",
|
|
|
|
|
"", tensor.name, model.TypeName(tensor.dataType),
|
|
|
|
|
model.DimsText(tensor.dim, tensor.dims), tensor.values,
|
|
|
|
|
//--- A tensor of text has no range to report
|
|
|
|
|
(tensor.dataType == 8)
|
|
|
|
|
? " text"
|
|
|
|
|
: StringFormat(" min %+.4f max %+.4f mean %+.4f",
|
|
|
|
|
tensor.minValue, tensor.maxValue, tensor.meanValue));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Report the whole model |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void ReportModel(void)
|
|
|
|
|
{
|
|
|
|
|
//--- Print which file was read
|
|
|
|
|
Print("ONNX Model Viewer -> ", model.Path());
|
|
|
|
|
//--- Print what the file says about itself
|
|
|
|
|
PrintFormat(" ir_version %d opset %d producer %s graph %s",
|
|
|
|
|
model.IrVersion(), model.Opset(), model.Producer(), model.GraphName());
|
|
|
|
|
//--- Print the shapes the model expects and returns
|
|
|
|
|
ReportPorts();
|
|
|
|
|
//--- Print the layers
|
|
|
|
|
ReportNodes();
|
|
|
|
|
//--- Print the weights
|
|
|
|
|
ReportTensors();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Expert initialization function |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
int OnInit()
|
|
|
|
|
{
|
|
|
|
|
//--- Read the whole file before reporting anything
|
|
|
|
|
if(!model.Load(ModelFile))
|
|
|
|
|
{
|
|
|
|
|
Print("ONNX Model Viewer: ", model.Error());
|
|
|
|
|
return(INIT_FAILED);
|
|
|
|
|
}
|
|
|
|
|
//--- Report what was read
|
|
|
|
|
ReportModel();
|
|
|
|
|
return(INIT_SUCCEEDED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Expert deinitialization function |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void OnDeinit(const int reason)
|
|
|
|
|
{
|
|
|
|
|
//--- Release the parsed structures
|
|
|
|
|
model.Clear();
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|