//+------------------------------------------------------------------+ //| ONNX.Price.Prediction.Test.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property description "Evaluation of the quality of the next Close price prediction by Python\\model.onnx.\n" "Start in strategy tester on EURUSD,H1, open prices, from 2023.01.01 to 2023.02.01" #resource "Python/model.onnx" as uchar ExtModel[] #define SAMPLE_SIZE 10 // bars count in sample as defined in Python\PricePredictionTraining.py // X, y = collect_dataset(df, history_size=10) long ExtHandle=INVALID_HANDLE; double ExtPredicted=0; datetime ExtNextBar=0; long ExtTests=0; long ExtRightDirection=0; double ExtSumAbsoluteError=0.0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { /* if(Symbol()!="EURUSD" || Period()!=PERIOD_H1) { Print("model must work with EURUSD,H1"); return(INIT_FAILED); } */ //--- create a model from static buffer ExtHandle=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(ExtHandle==INVALID_HANDLE) { Print("OnnxCreateFromBuffer error ",GetLastError()); return(INIT_FAILED); } //--- since not all sizes defined in the input tensor we must set them explicitly //--- first index - batch size, second index - series size, third index - number of series (OHLC) const long input_shape[] = {1,SAMPLE_SIZE,4}; if(!OnnxSetInputShape(ExtHandle,0,input_shape)) { Print("OnnxSetInputShape error ",GetLastError()); return(INIT_FAILED); } //--- since not all sizes defined in the output tensor we must set them explicitly //--- first index - batch size, must match the batch size of the input tensor //--- second index - number of predicted prices (we only predict Close) const long output_shape[] = {1,1}; if(!OnnxSetOutputShape(ExtHandle,0,output_shape)) { Print("OnnxSetOutputShape error ",GetLastError()); return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(ExtHandle!=INVALID_HANDLE) { OnnxRelease(ExtHandle); ExtHandle=INVALID_HANDLE; } } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- check new bar if(TimeCurrent()0 && delta_actual>0) || (delta_predict<0 && delta_actual<0)) ExtRightDirection++; Print("----------------------------------"); Print("times[0]: ", times[0], "; closes[0]: ", closes[0], "; times[1]: ", times[1], "; closes[1]: ", closes[1]); Print("ExtPredicted: ", ExtPredicted, "; ExtSumAbsoluteError (ExtPredicted-closes[1]): ", ExtSumAbsoluteError, "; delta_predict (ExtPredicted-closes[0]): ", delta_predict, "; delta_actual (closes[1]-closes[0]): ", delta_actual, "; ExtRightDirection: ", ExtRightDirection, "; ExtTests: ", ExtTests); } } } //+------------------------------------------------------------------+ //| Predict next price | //+------------------------------------------------------------------+ void PredictPrice(void) { static matrixf input_data(SAMPLE_SIZE,4); // matrix for prepared input data static vectorf output_data(1); // vector to get result static matrix mm(SAMPLE_SIZE,4); // matrix of horizontal vectors Mean static matrix ms(SAMPLE_SIZE,4); // matrix of horizontal vectors Std static matrix x_norm(SAMPLE_SIZE,4); // matrix for prices normalize //--- prepare input data matrix rates; //--- request last bars if(!rates.CopyRates(Symbol(),PERIOD_D1,COPY_RATES_OHLC,1,SAMPLE_SIZE)) { ExtPredicted=0.0; return; } //--- get series Mean vector m=rates.Mean(1); //--- get series Std vector s=rates.Std(1); //--- prepare matrices for prices normalization for(int i=0; i