const long ExtInputShape [] = {1,10,4}; // formulario de datos de salida del modelo const long ExtOutputShape[] = {1,1}; // formulario de datos de entrada del modelo #resource "Python/model.onnx" as uchar ExtModel[];// modelo en forma de recurso long handle; // manejador del modelo ulong predictions=0; // contador de pronósticos ulong confirmed=0; // contador de pronósticos exitosos //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- comprobaciones básicas if(_Symbol!="EURUSD") { Print("Symbol must be EURUSD, testing aborted"); return(-1); } if(_Period!=PERIOD_H1) { Print("Timeframe must be H1, testing aborted"); return(-1); } //--- creamos el modelo handle=OnnxCreateFromBuffer(ExtModel,ONNX_DEBUG_LOGS); //--- indicamos el formulario de los datos de entrada if(!OnnxSetInputShape(handle,0,ExtInputShape)) { Print("OnnxSetInputShape failed, error ",GetLastError()); OnnxRelease(handle); return(-1); } //--- indicamos el formulario de los datos de salida if(!OnnxSetOutputShape(handle,0,ExtOutputShape)) { Print("OnnxSetOutputShape failed, error ",GetLastError()); OnnxRelease(handle); return(-1); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- hemos finalizado el funcionamiento del modelo OnnxRelease(handle); //--- calculamos y mostramos las estadísticas de los pronósticos PrintFormat("Successfull predictions = %.2f %%",confirmed*100./double(predictions)); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { static datetime open_time=0; static double predict; //--- comprobamos la hora de apertura de la barra actual datetime time=iTime(_Symbol,_Period,0); if(time==0) { PrintFormat("Failed to get Time(0), error %d", GetLastError()); return; } //--- si la hora de apertura de la barra no ha cambiado, salimos hasta la siguiente llamada de OnTick if(time==open_time) return; //--- obtenemos los precios de cierre de las 2 últimas barras finalizadas double close[]; int recieved=CopyClose(_Symbol,_Period,1,2,close); if(recieved!=2) { PrintFormat("CopyClose(2 bars) failed, error %d",GetLastError()); return; } double delta_predict=predict-close[0]; // cambio de precio pronosticado double delta_actual=close[1]-close[0]; // cambio de precio real if((delta_predict>0 && delta_actual>0) || (delta_predict<0 && delta_actual<0)) confirmed++; //--- calculamos el precio de cierre de la nueva barra para comprobarlo en la siguiente barra matrix rates; //--- obtenemos 10 barras if(!rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,1,10)) return; //--- suministramos a la entrada un conjunto de vectores OHLC matrix x_norm=rates.Transpose(); vector m=x_norm.Mean(0); vector s=x_norm.Std(0); matrix mm(10,4); matrix ms(10,4); //--- rellenamos las matrices de normalización for(int i=0; i<10; i++) { mm.Row(m,i); ms.Row(s,i); } //--- normalizamos los datos de entrada x_norm-=mm; x_norm/=ms; //--- convertimos los datos de entrada normalizados al tipo float matrixf x_normf; x_normf.Assign(x_norm); //--- aquí obtenemos los datos de entrada del modelo, el pronóstico del precio vectorf y_norm(1); //--- iniciamos el modelo if(!OnnxRun(handle,ONNX_DEBUG_LOGS | ONNX_NO_CONVERSION,x_normf,y_norm)) { Print("OnnxRun failed, error ",GetLastError()); } //--- hacemos la transformación inversa para obtener el precio pronosticado y comprobarlo en una nueva barra predict=y_norm[0]*s[3]+m[3]; predictions++; // incrementamos el contador de pronósticos Print(predictions,". close prediction = ",predict); //--- recordamos la hora de apertura de la barra para comprobar el próximo tick open_time=time; } |