MetaTrader 5 build 3490: versão móvel do terminal web e novos métodos de matriz em MQL5

A nova versão do terminal web possui suporte total para dispositivos móveis. Agora sua interface se adapta automaticamente ao tamanho da tela, permitindo que os usuários trabalhem convenientemente na plataforma por meio de telefones e tablets com iOS e Android

4 novembro 2022

Versão móvel do terminal web

A nova versão do terminal web possui suporte total para dispositivos móveis. Agora sua interface se adapta automaticamente ao tamanho da tela, permitindo que os usuários trabalhem convenientemente na plataforma por meio de telefones e tablets com iOS e Android:

Novo terminal web com suporte para dispositivos móveis

Além disso, muitas correções e melhorias foram feitas no terminal web.

Novo terminal web MetaTrader 5 suporta todos os recursos que um trader moderno precisa. O aplicativo permite:

  • Trabalhar com contas demo e reais
  • Receber cotações de quaisquer instrumentos financeiros
  • Negociar em qualquer mercado
  • Realizar análises técnicas de cotações usando mais de 30 indicadores e 20 objetos gráficos
  • Analisar dados do Calendário Econômico

Terminal

  1. As funções do gerenciador de tarefas foram expandidas. Agora ele facilita o rastreio de recursos consumidos com ainda mais precisão.
    • Adicionada exibição do tamanho da pilha para fluxos
    • Adicionada a exibição de quantidade de chaveamentos
    • Adicionado reconhecimento de threads do sistema e threads em DLLs de terceiros
    • Adicionada exibição do tempo de operação no modo kernel. Um aumento neste indicador em relação ao tempo gasto no modo de usuário pode indicar problemas no sistema: problemas nos drivers, erros de hardware, hardware lento. Leia mais na documentação da Microsoft.
    • Adicionada exibição do tempo de operação no modo de usuário.

    Gerenciador OpenCL para gerenciar dispositivos disponíveis


  2. A guia OpenCL foi adicionada às configurações do terminal para gerenciar os dispositivos disponíveis. O novo gerenciador OpenCL permite especificar explicitamente os dispositivos que serão usados para cálculos.

    Gerenciador OpenCL para gerenciar dispositivos disponíveis

  3. Adicionada a substituição dos níveis de Stop Loss e Take Profit no livro de ofertas para contas que operam no modo FIFO (pode ser ativado no lado da corretora).

    O modo FIFO implica que as posições de cada instrumento devem ser fechadas na ordem em que foram abertas. Para garantir que as posições de fechamento por meio de níveis de stop estejam sempre em conformidade com a regra FIFO, no lado do terminal do cliente é implementada a seguinte lógica:

    Se houver várias posições para o mesmo instrumento, o posicionamento de níveis de stop para qualquer um deles resultará no posicionamento de níveis de stop similares para todos os outros. Assim, quando o nível for acionado, todas as posições serão fechadas em ordem de acordo com a regra FIFO.

    Agora, ao abrir o livro de ofertas para um instrumento que já possui posições, os níveis das posições existentes (se houver) serão inseridos automaticamente nos campos Stop Loss e Take Profit.

  4. Corrigida a exclusão dos níveis Stop Loss e Take Profit usando os botões "X" na seção "Caixa de Ferramentas\Negociação". O erro ocorria quando a função de negociação rápida era desativada. Agora, quando o botão for pressionado, uma caixa de diálogo de negociação será aberta com o valor vazio do nível correspondente.

  5. Feitas alterações no relatório de negociaçãorelatório de negociação - as legendas nos gráficos e o cálculo da comissão final foram corrigidos. Além disso, em alguns casos, o Profit incorreto era mostrado nas estatísticas do relatório, bem como valores incorretos nas dicas de ferramentas ao passar o mouse sobre os gráficos de patrimônio liquido e saldo.

MQL5

  1. Adicionados métodos vetoriais e matriciais CopyTicks e CopyTicksRange. Eles facilitam a cópia de matrizes de dados de ticks para vetores e matrizes.
    bool matrix::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
    bool vector::CopyTicks(string symbol,uint flags,ulong from_msc,uint count);
    
    bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
    bool matrix::CopyTicksRange(string symbol,uint flags,ulong from_msc,ulong to_msc);
    O tipo de dados a ser copiado é especificado no parâmetro flags usando a enumeração ENUM_COPY_TICKS. Estão disponíveis os seguintes valores:
    COPY_TICKS_INFO    = 1,       // ticks causados por mudanças em Bid e/ou Ask
    COPY_TICKS_TRADE   = 2,       // ticks causados por mudanças em Last e Volume
    COPY_TICKS_ALL     = 3,       // ticks com alterações
    COPY_TICKS_TIME_MS = 1<<8,    // tempo em milissegundos
    COPY_TICKS_BID     = 1<<9,    // preço Bid
    COPY_TICKS_ASK     = 1<<10,   // preço Ask
    COPY_TICKS_LAST    = 1<<11,   // preço Last
    COPY_TICKS_VOLUME  = 1<<12,   // volume
    COPY_TICKS_FLAGS   = 1<<13,   // sinalizadores de tick
    Quando vários tipos de dados são selecionados (disponível apenas para matrizes), a ordem das linhas na matriz corresponderá à ordem dos valores na enumeração.

  2. Expandidos os recursos dos métodos matrix::Assign e vector::Assign.

    Agora, um array ou vetor unidimensional pode ser atribuído à matriz:
    bool matrix::Assign(const vector &vec);
    O resultado será uma matriz de uma linha.

    Além disso, uma matriz agora pode ser atribuída a um vetor (com suavização da matriz):
    bool vector::Assign(const matrix &mat);
  3. Adicionados métodos de Swap para vetores e matrizes.
    bool vector::Swap(vector &vec);
    bool vector::Swap(matrix &vec);
    bool vector::Swap(double &arr[]);
    bool matrix::Swap(vector &vec);
    bool matrix::Swap(matrix &vec);
    bool matrix::Swap(double &arr[]);
    Cada array, vetor ou matriz aponta para um buffer de memória que contém os elementos de dado objeto. O método Swap realmente troca de lugar os ponteiros para esses buffers sem gravar os elementos na memória. Desse modo, a matriz continua sendo uma matriz e o vetor continua sendo um vetor. Quando você troca uma matriz e um vetor, obtém uma matriz de uma linha com elementos vetoriais e um vetor com elementos de matriz em uma representação plana (consulte o método Flat).
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
     {
    //---
      matrix a= {{1, 2, 3}, {4, 5, 6}};
      Print("a before Swap: \n", a);
      matrix b= {{5, 10, 15, 20}, {25, 30, 35, 40}, {45, 50, 55, 60}};
      Print("b before Swap: \n", b);  
    //--- swap matrix pointers
      a.Swap(b);
      Print("a after Swap: \n", a);
      Print("b after Swap: \n", b);
      /*
      a before Swap:
      [[1,2,3]
      [4,5,6]]
      b before Swap:
      [[5,10,15,20]
      [25,30,35,40]
      [45,50,55,60]]
      
      a after Swap:
      [[5,10,15,20]
      [25,30,35,40]
      [45,50,55,60]]
      b after Swap:
      [[1,2,3]
      [4,5,6]]
      */
      vector v=vector::Full(10, 7);
      Print("v before Swap: \n", v);
      Print("b before Swap: \n", b);
      v.Swap(b);
      Print("v after Swap: \n", v);
      Print("b after Swap: \n", b);
      /*
      v before Swap:
      [7,7,7,7,7,7,7,7,7,7]
      b before Swap:
      [[1,2,3]
      [4,5,6]]
      
      v after Swap:
      [1,2,3,4,5,6]
      b after Swap:
      [[7,7,7,7,7,7,7,7,7,7]]
      */
     }
    O método Swap também permite trabalhar com arrays dinâmicos (um array de tamanho fixo que não pode ser passado como parâmetro). Neste caso, a matriz pode ser de qualquer dimensão, mas de um tamanho acordado. Isso significa que o tamanho total de uma matriz ou vetor deve ser um múltiplo da dimensão zero da matriz. A dimensão zero de uma matriz é o número de elementos contidos no primeiro índice da matriz. Por exemplo, para um array tridimensional dinâmico double array[][2][3], a dimensão zero será o produto dos tamanhos da segunda e da terceira dimensão, ou seja, 2x3=6. Isso significa que tal array só pode ser usado no método Swap com matrizes e vetores cujo tamanho total seja múltiplo de 6: 6, 12, 18, 24, etc.

    Vamos mostrar isso com um exemplo:
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart()
     {
    //--- preenchemos a matriz 1x10 com o valor 7,0
      matrix m= matrix::Full(1, 10, 7.0);
      Print("matrix before Swap:\n", m);
    //--- tentamos realizar um intercâmbio entre uma matriz e um array
      double array_small[2][5]= {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
      Print("array_small before Swap:");
      ArrayPrint(array_small);
      if(m.Swap(array_small))
       {
        Print("array_small after Swap:");
        ArrayPrint(array_small);
        Print("matrix after Swap: \n", m);
       }
      else // o tamanho da matriz não é um múltiplo do tamanho da primeira dimensão do array
       {
        Print("m.Swap(array_small) failed. Error ", GetLastError());
       }
      /*
      matrix before Swap:
      [[7,7,7,7,7,7,7,7,7,7]]
      array_small before Swap:
               [,0]     [,1]     [,2]     [,3]     [,4]
      [0,]  1.00000  2.00000  3.00000  4.00000  5.00000
      [1,]  6.00000  7.00000  8.00000  9.00000 10.00000
      m.Swap(array_small) failed. Error 4006
      */
    //--- pegamos uma matriz maior e tentamos a realizar o intercâmbio novamente
      double array_static[3][10]= {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
         {2, 4, 6, 8, 10, 12, 14, 16, 18, 20},
         {3, 6, 9, 12, 15, 18, 21, 24, 27, 30}
       };
      Print("array_static before Swap:");
      ArrayPrint(array_static);
      if(m.Swap(array_static))
       {
        Print("array_static after Swap:");
        ArrayPrint(array_static);
        Print("matrix after Swap: \n", m);
       }
      else // um array estático não pode ser usado para troca com uma matriz
       {
        Print("m.Swap(array_static) failed. Error ", GetLastError());
       }
      /*
      array_static before Swap:
             [,0]     [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]     [,9]
      [0,]  1.00000  2.00000  3.00000  4.00000  5.00000  6.00000  7.00000  8.00000  9.00000 10.00000
      [1,]  2.00000  4.00000  6.00000  8.00000 10.00000 12.00000 14.00000 16.00000 18.00000 20.00000
      [2,]  3.00000  6.00000  9.00000 12.00000 15.00000 18.00000 21.00000 24.00000 27.00000 30.00000
      m.Swap(array_static) failed. Error 4006
      */
    //--- outra tentativa de trocar um array e uma matriz
      double array_dynamic[][10];    // array dinâmico
      ArrayResize(array_dynamic, 3); // colocamos o tamanho da primeira dimensão
      ArrayCopy(array_dynamic, array_static);
    //--- agora usamos um array dinâmico para realizar o intercâmbio
      if(m.Swap(array_dynamic))
       {
        Print("array_dynamic after Swap:");
        ArrayPrint(array_dynamic);
        Print("matrix after Swap: \n", m);
       }
      else //  não há erros
       {
        Print("m.Swap(array_dynamic) failed. Error ", GetLastError());
       }
      /*
      array_dynamic after Swap:
            [,0]    [,1]    [,2]    [,3]    [,4]    [,5]    [,6]    [,7]    [,8]    [,9]
      [0,] 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000 7.00000
      matrix after Swap:
      [[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30]]
      */
     }
  4. Adicionados métodos LossGradient para vetores e matrizes. Este método calcula um vetor ou matriz de derivadas parciais da função de perda em relação aos valores previstos. Na álgebra linear, esse vetor é chamado de gradiente e é usado no aprendizado de máquina.
    vector vector::LossGradient(const vector &expected,ENUM_LOSS_FUNCTION loss) const;
    matrix matrix::LossGradient(const matrix &expected,ENUM_LOSS_FUNCTION loss) const;
  5. Habilitado o uso de FOREIGN KEYS no SQLite, o que permite construir relacionamentos entre tabelas em consultas SQL.   Por exemplo:
    CREATE TABLE artist(
      artistid    INTEGER PRIMARY KEY, 
      artistname  TEXT
    );
    
    CREATE TABLE track(
      trackid     INTEGER, 
      trackname   TEXT, 
      trackartist INTEGER,
      FOREIGN KEY(trackartist) REFERENCES artist(artistid)
    );

  6. Corrigida a seleção do método de classe necessário dependendo da constância do método e do objeto.

MetaEditor

  1. O tamanho do comentário com suporte foi aumentado para commits para MQL5 Storage.  Comentários detalhados ao enviar alterações ao repositório são considerados uma boa prática ao trabalhar em grandes projetos, mas essas mensagens eram anteriormente limitadas a 128 caracteres. O limite agora está definido para 260 caracteres.

MetaTester

  1. Maior sensibilidade do interruptor de velocidade de teste no modo visual.

Correções de crash-logs.