Discussão do artigo "Uso de modelos ONNX em MQL5" - página 5

 
Belo artigo. O gráfico de previsão nos dados de teste é decepcionante. Você poderia muito bem pular toda essa modelagem/treinamento de DNN e simplesmente usar uma previsão do próximo preço igual ao último preço conhecido. Aposto que a precisão da previsão desse modelo trivial será maior do que a do seu modelo DNN. Sugiro comparar essas duas precisões e mostrá-las aqui. Em geral, usar DNN para prever preços é uma má ideia. Eles são mais adequados para a classificação dos padrões de preços (por exemplo, comprar, vender, manter). Além disso, o número de pesos no seu DNN é astronômico. Ele deve estar se ajustando demais.
 
Vladimir #:
Belo artigo. O gráfico de previsão nos dados de teste é decepcionante. Você poderia muito bem pular toda essa modelagem/treinamento de DNN e simplesmente usar uma previsão do próximo preço igual ao último preço conhecido. Aposto que a precisão da previsão desse modelo trivial será maior do que a do seu modelo DNN. Sugiro comparar essas duas precisões e mostrá-las aqui. Em geral, usar DNN para prever preços é uma má ideia. Eles são mais adequados para a classificação dos padrões de preços (por exemplo, comprar, vender, manter). Além disso, o número de pesos no seu DNN é astronômico. Ele deve estar se ajustando demais.

Obrigado , Vladimir.
Apenas para discussão, quando o tempo permitir, eu modificaria esse modelo para fazer a classificação para comparação.

Se tiver ideias, entre em contato comigo.

Vladimir
Vladimir
  • 2022.04.30
  • www.mql5.com
Trader's profile
 
const long input_shape[] = {1, input_count};
const long output_shape[] = {1, output_count};

O tutorial fornece uma entrada de um lote SAMPLE_SIZE número de entradas próximas, você quer um lote de entradas input_count.

Além disso, seu modelo não usa floats como entradas, mas duplas,

Nota do moderador: Esta postagem está fora de sequência porque as postagens abaixo foram movidas de outro tópico. Consulte a postagem abaixo.

 
Podemos solucionar esse modelo ONNX juntos?

Olá comunidade MQL5, estou tentando seguir este tutorial sobre como usar o ONNX em seus EAs. No tutorial, uma rede neural foi o modelo escolhido, e eu usei uma árvore com gradiente aumentado.

Criei o modelo usando o pacote InterpretML Python e o exportei para o ONNX usando o ebm2onnx.

Farei um resumo do processo pelo qual o modelo foi treinado.

1) O modelo foi treinado com 5 entradas, OHLC e Altura, sendo que a Altura é calculada como ((H + L) / 2) - C.

2) O modelo é um classificador binário, com o objetivo de classificar o próximo candle como PARA CIMA (1) ou PARA BAIXO (0).

Dados de treinamento do modelo

Os dados usados para treinar o modelo.

3) O modelo foi então exportado para o formato ONNX

Representação ONNX

Representação do modelo ONNX.


Para fazer o modelo funcionar, desviei-me do código do tutorial e continuei editando o código para tentar fazer o modelo ONNX funcionar, mas agora realmente não sei o que estou fazendo de errado. Continuo recebendo um erro informando que o identificador do modelo é inválido.

Anexei o código MQL5 abaixo.

Agora vou resumir as etapas que segui em meu código e que se desviam do que está no tutorial, e também explicarei por que me desviei do tutorial

1) LINHA 57: Definição da forma de entrada do modelo.
No tutorial, foram usadas 3 dimensões para definir a forma de entrada e saída, ou seja, {1,SAMPLE_SIZE,1}; no entanto, quando segui essa abordagem, continuei recebendo um erro, especificamente o erro 5808. Após o processo usual de tentativa e erro, percebi que se usasse apenas uma dimensão, o número de entradas, o erro desapareceria.

2) LINHA 68: Configuração da forma de saída do modelo.

A mesma lógica acima.

Os outros desvios que fiz não afetam o modelo, por exemplo, mantive o controle do tempo usando a lógica que achei mais intuitiva do que a lógica implementada no tutorial. Não precisei normalizar as entradas porque se trata de um modelo baseado em árvore.


Se você puder identificar outros erros que cometi, gostaria de receber sua opinião.

//+------------------------------------------------------------------+
//|ONNX.mq5 |
//|Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com
//+------------------------------------------------------------------+
//Meta propriedades
#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com"
#property version   "1.00"

//Biblioteca comercial
#include <Trade\Trade.mqh>

//Lendo nosso modelo ONNX e armazenando-o em uma matriz de dados
#resource "\\Files\\Python\\Volatility_75_EBM.onnx" as uchar ExtModel[]

/Definições de palavras-chave personalizadas
#define   SAMPLE_SIZE 998
#define   PRICE_UP 1
#define   PRICE_DOWN 0

/Variáveis globais
long     ExtHandle = INVALID_HANDLE;
int      ExtPredictedClass = -1;
datetime ExtNextBar = 0;
datetime ExtNextMinute =0;
float    ExtMin = 0;
float    ExtMax = 0;
double   min_volume;
CTrade   ExtTrade;

//Entradas
int input lot_mutliple = 1; //Quantas vezes maior que o lote mínimo devemos inserir?

int OnInit()
  {
   /Verificar se o símbolo e o período de tempo estão em conformidade com as condições de treinamento
   if(_Symbol != "Volatility 75 Index" || _Period != PERIOD_M1)
       {
            Comment("Model must be used with the Volatility 75 Index on the 1 Minute Chart");
            return(INIT_FAILED);
       }
    
    /Criar um modelo ONNX a partir de nossa matriz de dados
    ExtHandle = OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT);
    Print("ONNX Create from buffer status ",ExtHandle);
    
    /Verificar se o identificador é válido
    if(ExtHandle == INVALID_HANDLE)
      {
            Comment("ONNX create from buffer error ", GetLastError());
            return(INIT_FAILED);
      }
   
   /Definir forma de entrada
   long input_count = OnnxGetInputCount(ExtHandle);   
   const long input_shape[] = {input_count};
   Print("Total model inputs : ",input_count);
   if(!OnnxSetInputShape(ExtHandle,0,input_shape))
      {
            Comment("ONNX set input shape error ", GetLastError());
            OnnxRelease(ExtHandle);
            return(INIT_FAILED);
      }
      
   /Definir forma de saída
   long output_count = OnnxGetOutputCount(ExtHandle);
   const long output_shape[] = {output_count};
   Print("Total model outputs : ",output_count);
   if(!OnnxSetOutputShape(ExtHandle,0,output_shape))
      {
            Comment("ONNX set output shape error ", GetLastError());
            OnnxRelease(ExtHandle);
            return(INIT_FAILED);
      }
    
    /Obter o volume mínimo de negociação permitido 
    min_volume = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);  
    return(INIT_SUCCEEDED);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Função de desinicialização de especialista|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ExtHandle != INVALID_HANDLE)
      {
         OnnxRelease(ExtHandle);
         ExtHandle = INVALID_HANDLE;
      }
  }
//+------------------------------------------------------------------+
//| Função de tique de especialista|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   / Rastreadores de tempo
   static datetime time_stamp;
   datetime time = iTime(_Symbol,PERIOD_M1,0);
      
    /Verificar a nova barra
     if(time_stamp != time)
      {
         time_stamp = time;
         
         PredictedPrice();
         Print("Predicted class: ",ExtPredictedClass);
         
         if(ExtPredictedClass == PRICE_UP || ExtPredictedClass == PRICE_DOWN)
            if(PositionSelect(_Symbol))
               CheckForClose();
            if(PositionsTotal() == 0)
               CheckForOpen();
      }
   
  }
//+------------------------------------------------------------------+

void CheckForOpen(void)
   {
      ENUM_ORDER_TYPE signal = WRONG_VALUE;
      
      // Verificar sinais
      if(ExtPredictedClass == PRICE_DOWN)
         {
            signal = ORDER_TYPE_SELL;
         }
         
      else if(ExtPredictedClass == PRICE_UP)
         {
            signal = ORDER_TYPE_BUY;
         }
         
      if(signal != WRONG_VALUE && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         {
            double price, sl = 0 , tp = 0;
            double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
            double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
            
            if(signal == ORDER_TYPE_SELL)
               {
                  price = bid;
               }
               
           else
               {
                  price = ask;
               }
               
            Print("Opening a new position: ",signal);  
            ExtTrade.PositionOpen(_Symbol,signal,min_volume,price,0,0);
         }
   }
   
void CheckForClose(void)
   {
      bool bsignal = false;
      
      long type = PositionGetInteger(POSITION_TYPE);
      
      if(type == POSITION_TYPE_BUY && ExtPredictedClass == PRICE_DOWN)
         bsignal = true;
         
      if(type == POSITION_TYPE_SELL && ExtPredictedClass == PRICE_UP)
         bsignal = true;
         
         if(bsignal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
            {
                  ExtTrade.PositionClose(_Symbol,3);
                  CheckForOpen();
            }
   }
   
 void PredictedPrice(void)
   {
      vectorf output_data(1);
      float   open  = float(iOpen(_Symbol,PERIOD_M1,1));
      float   high  = float(iHigh(_Symbol,PERIOD_M1,1));
      float   low   = float(iLow(_Symbol,PERIOD_M1,1));
      float   close = float(iClose(_Symbol,PERIOD_M1,1));
      float   height =  float((((high + low) / 2) - close));
      Print("Current open ",open);
      Print("Current high ",high);
      Print("Current low ",low);
      Print("Current close ",close);
      Print("Current height ",height);
      vectorf input_data = {open,high,low,close,height};
      
      Print("Input vector: ",input_data);
      
       if(!OnnxRun(ExtHandle,ONNX_NO_CONVERSION,input_data,output_data))
         {
            Print("ONNX run error : ",GetLastError());
            OnnxRelease(ExtHandle);
         }
        
       int predicted = int(output_data[0]);
       
       Print("Model prediction: ",predicted);
       Print(output_data);
       
       if(predicted == 1)
         {
            ExtPredictedClass = PRICE_UP;
         }
         
       else if(predicted == 0)
         {
            ExtPredictedClass = PRICE_DOWN;
         }
         
         Comment("Model Prediction: ", ExtPredictedClass);
   }



Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Discussão do artigo "Como usar modelos ONNX em MQL5"

Stian Andreassen, 2023.12.08 20:51

const long input_shape[] = {1, input_count};
const long output_shape[] = {1, output_count};

O tutorial fornece uma entrada de um lote SAMPLE_SIZE número de entradas próximas, você quer um lote de entradas input_count.

Além disso, seu modelo não usa floats como inputs, mas sim doubles,



Obrigado por compartilhar Sitan, apliquei o que você indicou, mas o erro ainda está lá


Um lote de input_count

Um lote de entradas input_count.

Definir a entrada como dupla

Definir a entrada como double

Mensagem de erro

Mensagem de erro.


Arquivos anexados:
 
amuchirai Zororo Ndawana #:
Podemos solucionar esse modelo ONNX juntos?

Hello MQL5 community, I've been trying to follow this tutorial on how to use ONNX in your EA's. In the tutorial a neural network was the model of choice, I've used a gradient boosted tree. 

Criei o modelo usando o pacote InterpretML Python e o exportei para o ONNX usando o ebm2onnx.

Farei um resumo do processo pelo qual o modelo foi treinado.

1) O modelo foi treinado com 5 entradas, OHLC e Altura, sendo que a Altura é calculada como ((H + L) / 2) - C.

2) O modelo é um classificador binário, com o objetivo de classificar o próximo candle como PARA CIMA (1) ou PARA BAIXO (0).

Os dados usados para treinar o modelo.

3) O modelo foi então exportado para o formato ONNX

Representação do modelo ONNX.


Para fazer o modelo funcionar, desviei-me do código do tutorial e continuei editando o código para tentar fazer o modelo ONNX funcionar, mas agora realmente não sei o que estou fazendo de errado. Continuo recebendo um erro informando que o identificador do modelo é inválido.

Anexei o código MQL5 abaixo.

Agora vou resumir as etapas que segui em meu código e que se desviam do que está no tutorial, e também explicarei por que me desviei do tutorial

1) LINHA 57: Definição da forma de entrada do modelo.
No tutorial, foram usadas 3 dimensões para definir a forma de entrada e saída, ou seja, {1,SAMPLE_SIZE,1}; no entanto, quando segui essa abordagem, continuei recebendo um erro, especificamente o erro 5808. Após o processo usual de tentativa e erro, percebi que se usasse apenas uma dimensão, o número de entradas, o erro desapareceria.

2) LINHA 68: Configuração da forma de saída do modelo.

A mesma lógica acima.

Os outros desvios que fiz não afetam o modelo, por exemplo, mantive o controle do tempo usando a lógica que achei mais intuitiva do que a lógica implementada no tutorial. Não precisei normalizar as entradas porque se trata de um modelo baseado em árvore.


Se você puder identificar outros erros que cometi, gostaria de receber sua opinião.





Obrigado por compartilhar Sitan, apliquei o que você indicou, mas o erro ainda está lá


Um lote de inputs input_count.

Definir a entrada como dupla

Mensagem de erro.


Parece que a MQL5 (ou melhor, o ONNXMLTools) ainda não é compatível com o ONNX do EBM:

https://www.mql5.com/pt/docs/onnx/onnx_conversion

Se você consultar os anexos do ONNX (especialmente model.eurusd.D1.10.class.onnx, que usa 4 entradas) em https://www.mql5.com/pt/articles/12484 e usar o Netron(versão da Web) para visualizar os arquivos onnx, verá as diferenças.

Acredito que os dois artigos a seguir também o ajudariam a entender melhor:

Modelos de regressão da biblioteca Scikit-learn e sua exportação para o ONNX

Modelos de classificação na biblioteca Scikit-Learn e sua exportação para o ONNX

Wrapping ONNX models in classes
Wrapping ONNX models in classes
  • www.mql5.com
Object-oriented programming enables creation of a more compact code that is easy to read and modify. Here we will have a look at the example for three ONNX models.
 

Olá a todos,


Estamos tentando usar uma rede neural do keras com 11 preditores em um determinado momento (tamanho de lote 32) para fazer previsões no XauUsd (em que a saída é um número singular entre 0 e 1). Primeiro, carregamos a partir do OnnxCreatefrombuffer (porque o próprio OnnxCreate não funciona para nós), depois sempre recebemos um erro no estágio OnnxRun, onde anexei os dois erros abaixo. Qualquer ajuda sobre a dimensão a ser remodelada para a entrada, em que formato colocar nosso vetor de previsão (se é que ele deve ser um vetor?) ou qualquer ajuda ou sugestão de sintaxe para ajudar a resolver esses erros seria incrível. Tentamos remodelar para todos os tipos de combinações de vetores 32,1,11 e não tivemos sorte e realmente não temos ideia das próximas etapas. Muito obrigado a todos que puderem ajudar! Ben.

' erro 5808'

' ONNX: parâmetro de entrada #0 tensor tem dimensão errada [0], tente usar OnnxSetInputShape'

'ONNX: tamanho inválido do parâmetro de entrada n.º 0, tamanho esperado de 1408 bytes em vez de 480'

 

Olá, tentei usar o script de arquivo

OnnxModelInfo.mq5

mas não consigo fazer com que funcione. O que estou fazendo de errado? Isso não pode ser tão complicado!

Copiei e colei o script OnnxModelInfo e salvei na pasta Files

Tenho um modelo Onnx (em anexo)

e quando compilo o script, aparecem 21 erros.

Alguém pode me ajudar com isso? Por favor

'element_type' - undeclared identifier  onnx read file.mq5      60      49
'element_type' - parameter for EnumToString must be an enumeration      onnx read file.mq5      60      49
'dimensions' - undeclared identifier    onnx read file.mq5      62      17
'dimensions' - undeclared identifier    onnx read file.mq5      64      37
'[' - array required    onnx read file.mq5      64      47
'dimensions' - undeclared identifier    onnx read file.mq5      65      51
'[' - array required    onnx read file.mq5      65      61
'dimensions' - undeclared identifier    onnx read file.mq5      66      33
'dimensions' - undeclared identifier    onnx read file.mq5      68      23
'[' - array required    onnx read file.mq5      68      33
'dimensions' - undeclared identifier    onnx read file.mq5      71      48
'[' - array required    onnx read file.mq5      71      58
'dimensions' - undeclared identifier    onnx read file.mq5      80      33
'dimensions' - undeclared identifier    onnx read file.mq5      82      35
'[' - array required    onnx read file.mq5      82      45
'dimensions' - undeclared identifier    onnx read file.mq5      100     28
';' - unexpected token  onnx read file.mq5      102     45
'<' - l-value required  onnx read file.mq5      100     17
cannot implicitly convert type 'string' to 'bool'       onnx read file.mq5      102     21
l-value required        onnx read file.mq5      102     20
'(' - unbalanced left parenthesis       onnx read file.mq5      100     9
empty controlled statement found        onnx read file.mq5      102     45
Arquivos anexados:
model.onnx  295 kb
 
MetaQuotes:

Novo artigo Uso de modelos ONNX em MQL5 foi publicado:

Autor: MetaQuotes

Olá senhores.

Alguém pode me ajudar, pois no final do processo em python, sai o seguinte erro: AttributeError: 'Sequential' object has no attribute 'output_names'. Não sei muito de python, nem de programação. Portanto qualquer ajuda será bem vinda! Obrigado.

 
Olá, senhores.

Alguém pode me ajudar, pois no final do processo em python, aparece o seguinte erro: AttributeError: O objeto 'Sequential' não possui o atributo 'output_names'. Não sei muito sobre Python ou programação. Portanto, qualquer ajuda será bem-vinda! Obrigado.
 
Alberto Henrique Tacoronte #Olá senhores. Alguém pode me ajudar, pois no final do processo em python, sai o seguinte erro: AttributeError: 'Sequential' object has no attribute 'output_names'. Não sei muito de python, nem de programação. Portanto qualquer ajuda será bem vinda! Obrigado.

Olá, Alberto, por favor, poste o trecho do seu código [utilizando o botão do CÓDIGO (Alt -S)] onde está ocorrendo o erro que alguém que conheça Python (MetaTrader para Python | Modelos ONNX) poderá apontar a solução...